Adam Jones
Adam Jones

Reputation: 113

Waiting until an external process has been completed

I have a method that is called, although I would like the message box to be shown after the method has been completed (right now the message box is shown straight after the method is called):

if (Check == true)
{
    StartConvIpod();
}
else
{

}
MessageBox.Show("Operation Successful!");

StartConvIpod:

      private void StartConvIpod()
        {

            string res = Directory.EnumerateFiles("dump").
    OrderBy(x => File.GetCreationTime(x)).Last();

            string sub = res.Substring(5);

            string sub2 = sub.Substring(0, sub.Length - 4);


            Process p = new Process();
            p.StartInfo.WorkingDirectory = "dump";
            p.StartInfo.FileName = "ffmpeg.exe";
            p.StartInfo.Arguments = "-i " + sub + " -f mp4 -vcodec mpeg4 -b 700k -aspect 4:3 -r 23.98 -s 320x240 -acodec ac3 -ar 48000 iPodConversions\\" + sub2 + ".mp4";
            p.Start();
}

Upvotes: 8

Views: 8996

Answers (4)

Jeremy Thompson
Jeremy Thompson

Reputation: 65544

Use the Process.Exited Event as per the MSDN Documentation for the Process Exit Event and poll for 30 seconds till the Exited event fires and check the ExitCode.

private Process myProcess = new Process();
private int elapsedTime;
private bool eventHandled;

public void RunFfmpeg(string arguments)
{    
    elapsedTime = 0;
    eventHandled = false;

    try
    {
        myProcess.StartInfo.FileName = "ffmpeg.exe";
        myProcess.StartInfo.Arguments = arguments;
        myProcess.StartInfo.CreateNoWindow = true;
        myProcess.EnableRaisingEvents = true;
        myProcess.Exited += new EventHandler(myProcess_Exited);
        myProcess.Start();    
    }
    catch (Exception ex)
    {
        Console.WriteLine("An error occurred trying to print \"{0}\":" + "\n" + ex.Message, fileName);
        return;
    }

    // Wait for Exited event, but not more than 30 seconds.
    const int SLEEP_AMOUNT = 100;
    while (!eventHandled)
    {
        elapsedTime += SLEEP_AMOUNT;
        if (elapsedTime > 30000)
        {
            break;
        }
        Thread.Sleep(SLEEP_AMOUNT);
    }
}

private void myProcess_Exited(object sender, System.EventArgs e)
{    
    eventHandled = true;
    Console.WriteLine("Exit time:    {0}\r\n" +
        "Exit code:    {1}\r\nElapsed time: {2}", myProcess.ExitTime, myProcess.ExitCode, elapsedTime);
}

Upvotes: 0

vcsjones
vcsjones

Reputation: 141598

You have a couple of options. In StartConvIpod, you can put p.WaitForExit() after p.Start();

That'll work, but will probably block your UI Thread (make it appears your application is frozen). Instead, I'd change your UI to some sort of "working" state, such as disabling the "Start Conversion" button, and set a label to "Converting" (just as an example). Then I'd register on the p.Exited event and when your process is exited. When the event is raised, you can notify the UI your conversion is complete and check the exit code from the process.

Upvotes: 3

CassOnMars
CassOnMars

Reputation: 6181

Use this at the end of your code:

p.WaitForExit();

Don't forget to check its return value to make sure it actually was successful, though:

if(p.ExitCode == 0) { // Or whatever return code you're expecting
    //...
}

Upvotes: 8

Jason Down
Jason Down

Reputation: 22161

You'll want to add this:

p.Start();
p.WaitForExit(); // or p.WaitForExit(Timeout-Period-In-Milliseconds);

Upvotes: 11

Related Questions