Home All Groups Group Topic Archive Search About

show stderr output dynamically

Author
3 Dec 2008 6:36 PM
Andrus
Long-running backup program mybackup.exe wrotes status messages to stderr
How to show messages written to stderr if this program is running ?

I tried code below but it shows stderr output only after program is
completed.

Andrus.

using System;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;

    class DBCreate
    {
        internal string msg;

        internal void dbCreate()
        {
            ProcessStartInfo pinfo = new ProcessStartInfo();
            pinfo.ErrorDialog = true;
            pinfo.FileName = Environment.CurrentDirectory +
"\\mybackup.exe";
            pinfo.WindowStyle = ProcessWindowStyle.Maximized;
            pinfo.RedirectStandardError = true;
            pinfo.UseShellExecute = false;
            pinfo.RedirectStandardOutput = true;
            Process p = new Process();
            p.EnableRaisingEvents = true;
            p.StartInfo = pinfo;
            p.Start();
            msg = p.StandardError.ReadToEnd();

            while (!p.HasExited)
                System.Threading.Thread.Sleep(1000);

            p.WaitForExit();
            p.Close();
        }
    }

    public static class BackupCopy
    {
        public static void Run()
        {
            var bw = new BackupbackgroundWorker();
            bw.RunWorkerAsync();
        }
    }

    class BackupbackgroundWorker : BackgroundWorker
    {
        string msg;
        DBCreate db;

        protected override void OnDoWork(DoWorkEventArgs e)
        {
            db = new DBCreate();
            db.dbCreate();
            msg = db.msg;
            base.OnDoWork(e);
        }

        protected override void
OnRunWorkerCompleted(RunWorkerCompletedEventArgs e)
        {
            base.OnRunWorkerCompleted(e);
            MessageBox.Show( msg );
        }
    }

Author
3 Dec 2008 7:42 PM
Peter Duniho
On Wed, 03 Dec 2008 10:36:28 -0800, Andrus <kobrule***@hot.ee> wrote:

> Long-running backup program mybackup.exe wrotes status messages to stderr
> How to show messages written to stderr if this program is running ?
>
> I tried code below but it shows stderr output only after program is 
> completed.

Right.  Because you told it to ReadToEnd(), which won't return until after 
the program is completed.  You need to just read normally from the 
StandardError output if you want to be able to read data as it's 
available.  Of course, if you do that, you will need a better approach to 
displaying the output than storing the result in a string and displaying 
it in a MessageBox at the end.

Note also that you should not redirect StandardOutput unless you are also 
going to read from that output, and if you do so, you will need to either 
read asynchronously from at least one of the outputs, or read from two 
different threads.

Some other comments:

     -- For a process that has already exited, calling Process.Close() is 
superfluous.

     -- I would not inherit BackgroundWorker.  You can of course do it as 
you've shown here and get it to work, but by inheriting and overriding 
rather than just handling events of BackgroundWorker directly, you create 
a design where someone could instantiate the class, subscribe to the 
event, and then not have their event handler executed right when 
RunWorkerAsync() is called.

On the latter point, I have to admit that I think it wouldn't have been a 
bad thing for BackgroundWorker to be sealed.  So most of my concern comes 
from the fact that I tend to treat it as if it were sealed.  But in any 
case, I don't see anything you've done in your derived class that cannot 
be done without inheritance, which suggests you shouldn't have inherited 
the class.

Pete
Are all your drivers up to date? click for free checkup

Author
3 Dec 2008 8:19 PM
Ben Voigt [C++ MVP]
>     -- For a process that has already exited, calling Process.Close()
> is superfluous.

False.  Windows has to keep a bunch of data structures around for every
process, even after exit, until every last handle to it is closed.  This is
so that other programs can inspect the exit code and wait for the process to
exit.  Ok, .NET's garbage collector would close that handle eventually when
it decided you weren't ever going to use it again, but better to be
deterministic.
Author
12 Dec 2008 9:15 PM
Ben Voigt [C++ MVP]
"Ben Voigt [C++ MVP]" <rbv@nospam.nospam> wrote in message
news:OUqTsRYVJHA.2084@TK2MSFTNGP06.phx.gbl...
>>     -- For a process that has already exited, calling Process.Close()
>> is superfluous.
>
> False.  Windows has to keep a bunch of data structures around for every
> process, even after exit, until every last handle to it is closed.  This
> is so that other programs can inspect the exit code and wait for the
> process to exit.  Ok, .NET's garbage collector would close that handle
> eventually when it decided you weren't ever going to use it again, but
> better to be deterministic.

Also these data structures assigned to exited processes because some other
process may still be using them are called "zombie processes" in many other
OSes.

Bookmark and Share