4

Wondering if you could help me?

I have a application(app1) that can launch another application(app2), whilst app2 is runnning app1 is able to do some mointoring on folder/files that change during the life cycle of app2. I can do this fine and runs perfect.

However I was wondering if there any way that I can monitor app2 to see when it has been terminated so that I can tell app1 one to stop tracking?

I don't have the source code for app2 so I am unable to edit it to send a signal to app1.

Thanks for your time.

Matt

Navid Rahmani
  • 7,848
  • 9
  • 39
  • 57
Matthew Deloughry
  • 292
  • 2
  • 7
  • 25

3 Answers3

2

You could do it like that:

var p = Process.Start("app2.exe");
// do start watching here
p.WaitForExit();
// do stop watching here

Note that it is not production-quality code because if app2 will hang - this code will wait for it forever. There's overload that allows to specify timeout thus you could finish waiting beforehand.

Or alternatively use Process.Exited event as Navid suggested.

Ivan Danilov
  • 14,287
  • 6
  • 48
  • 66
  • This does look like a good soloution can I ask though, what benifits this has over Navid's suggestion?(and vise versa?) Thanks – Matthew Deloughry Jun 19 '11 at 21:12
  • Well, waiting for a process with `WaitForExit` holds your thread busy, so you can't do anything else. If you watching has asynchronous nature like getting notifications called on thread pool threads by the OS - it is ok. On the contrary if you have some UI and can't take its thread (because UI will be 'Not responding' while the UI thread is busy) - event is more suitable. – Ivan Danilov Jun 19 '11 at 21:17
  • This is synchronous and straight-forward. The other method frees doesn't tie up your application while the other one runs. – Brad Bruce Jun 19 '11 at 21:19
2

If you are using Process use Process.Exited event

Consider this event can occur only if EnableRaisingEvents property is true

Edit: If you need the output of the app2 @Ivan's answer is better you need to wait for exit.

Navid Rahmani
  • 7,848
  • 9
  • 39
  • 57
0

This is what I've used on a few projects without any issues (so far).

using System.Diagnostics;
using System;

namespace [whatever]
{
    class Executor {
        public event EventHandler Completed;
        public event DataReceivedEventHandler DataReceived;
        public event DataReceivedEventHandler ErrorReceived;

        public void callExecutable(string executable, string args, string workingDir){
            string commandLine = executable;
            ProcessStartInfo psi = new ProcessStartInfo(commandLine);
            psi.UseShellExecute = false;
            psi.LoadUserProfile = false;
            psi.RedirectStandardOutput = true;
            psi.RedirectStandardError = true;
            psi.WindowStyle = ProcessWindowStyle.Minimized;
            psi.CreateNoWindow = true;
            psi.Arguments = args;
            psi.WorkingDirectory = System.IO.Path.GetDirectoryName(executable);
            psi.WorkingDirectory = workingDir;
            Process p = new Process();
            p.StartInfo = psi;
            try{
                p.EnableRaisingEvents = true;
                p.Start();
                if (DataReceived != null) p.OutputDataReceived += DataReceived;
                if (ErrorReceived != null) p.ErrorDataReceived += ErrorReceived;
                p.BeginOutputReadLine();
                p.BeginErrorReadLine();
                p.Exited += new EventHandler(p_Exited);
            }
            catch (Exception ex){
                //log.Error(ex.Message);
            }
        }

        void p_Exited(object sender, EventArgs e) {
            (sender as Process).Close();
            (sender as Process).Dispose();
            if (Completed != null) {
                Completed(this, e);
            }
        }
    }
}
/*
    //In another class
        private void CallProgram() {
            Executor exec = new Executor();
            exec.Completed += new EventHandler(exec_Completed);
            exec.DataReceived += new System.Diagnostics.DataReceivedEventHandler(exec_DataReceived);
            exec.ErrorReceived += new System.Diagnostics.DataReceivedEventHandler(exec_ErrorReceived);
            exec.callExecutable([Program Name],
                [Arguments],
                [Working Dir]);
        }

        void exec_Completed(object sender, EventArgs e) {
            MessageBox.Show("Finshed");
        }

        void exec_DataReceived(object sender, System.Diagnostics.DataReceivedEventArgs e) {
            if (e.Data != null) {
                AddText(e.Data.ToString());
            }
        }

        void exec_ErrorReceived(object sender, System.Diagnostics.DataReceivedEventArgs e) {
            if (e.Data != null) {
                AddText(e.Data.ToString());
            }
        }

        // this handles the cross-thread updating of a winforms control
        private void AddText(string textToAdd) {
            if (textBox1.InvokeRequired) {
                BeginInvoke((MethodInvoker)delegate() { AddText(textToAdd); });
            }
            else {
                textBox1.AppendText(textToAdd);
                textBox1.AppendText("\r\n");
                textBox1.Refresh();
            }
        }

*/
Brad Bruce
  • 7,638
  • 3
  • 39
  • 60