Зачекайте, поки процес закінчиться


206

У мене є програма, яка це робить

Process.Start()

запустити ще одну програму "ABC". Я хочу зачекати, поки ця програма закінчиться (процес відмирає) і продовжувати виконання. Як я можу це зробити?

Може бути кілька примірників запуску програми "ABC" одночасно.


І якщо ви хочете зробити це асинхронно (тобто підняти подію після завершення), ви можете подивитися тут SO.
Метт

Відповіді:


401

Я думаю, ти просто хочеш цього:

var process = Process.Start(...);
process.WaitForExit();

Про метод див. На сторінці MSDN . Він також має перевантаження, де ви можете вказати час очікування, тому ви потенційно не чекаєте вічно.


137

Використовувати Process.WaitForExit? Або підписатися на Process.Exitedподію, якщо ви не хочете блокувати? Якщо це не робить те, що ви хочете, будь ласка, дайте нам більше інформації про ваші вимоги.


безумовно , хороша інформація з Process.Exited, але ОП дійсно говорив «почекайте»
Mike M

8
@MikeM: Ось чому я посилався WaitForExitспочатку ... у деяких випадках ви можете виконати більше коду, коли щось закінчується, але це не означає, що вам потрібно блокувати поточний потік.
Джон Скіт

7
Якщо ви збираєтеся використовувати Process.Exitedподію, я вважаю, що ви повинні заздалегідь налаштувати процес, встановивши Process.EnableRaisingEventsзначення true. Хоча, враховуючи, що цьому питанню більше трьох років, можливо, це Process.EnableRaisingEventsбуло не на момент запитання.
Буде

Я завершився на цій сторінці, шукаючи назву Process.Exitedподії. Дякую! +1 для повноти
Чад

36

У своїй заяві я виконую наступне:

Process process = new Process();
process.StartInfo.FileName = executable;
process.StartInfo.Arguments = arguments;
process.StartInfo.ErrorDialog = true;
process.StartInfo.WindowStyle = ProcessWindowStyle.Minimized;
process.Start();
process.WaitForExit(1000 * 60 * 5);    // Wait up to five minutes.

Є кілька додаткових функцій, які можуть бути вам корисними ...


17

Ви можете скористатись функцією очікування виходу, або ви можете зафіксувати властивість HasExited та оновити інтерфейс користувача, щоб інформувати користувача (управління очікуванням):

System.Diagnostics.Process process = System.Diagnostics.Process.Start("cmd.exe");
while (!process.HasExited)
{
    //update UI
}
//done

9

У мене був випадок, коли Process.HasExitedпісля закриття вікна, що належить до процесу, не змінився. Так Process.WaitForExit()само не вийшло. Мені довелося стежити за тим, Process.Respondingщо перейшов у помилку після закриття вікна:

while (!_process.HasExited && _process.Responding) {
  Thread.Sleep(100);
}
...

Можливо, це комусь допомагає.



1

Посилаючись на приклад Microsoft: [ https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.process.enableraisingevents?view=netframework-4.8]

Найкраще було б встановити:

myProcess.EnableRaisingEvents = true;

в іншому випадку Кодекс буде заблоковано. Також додаткові властивості не потрібні.

// Start a process and raise an event when done.
myProcess.StartInfo.FileName = fileName;
// Allows to raise event when the process is finished
myProcess.EnableRaisingEvents = true;
// Eventhandler wich fires when exited
myProcess.Exited += new EventHandler(myProcess_Exited);
// Starts the process
myProcess.Start();

// Handle Exited event and display process information.
private void myProcess_Exited(object sender, System.EventArgs e)
{
Console.WriteLine(
                  $"Exit time    : {myProcess.ExitTime}\n" +
                  $"Exit code    : {myProcess.ExitCode}\n" +
                  $"Elapsed time : {elapsedTime}");
}

0

Як каже Джон Скіт, використовуйте Process.Exited:

proc.StartInfo.FileName = exportPath + @"\" + fileExe;
proc.Exited += new EventHandler(myProcess_Exited);
proc.Start();
inProcess = true;

while (inProcess)
{
    proc.Refresh();
    System.Threading.Thread.Sleep(10);
    if (proc.HasExited)
    {
        inProcess = false;
    }
}

private void myProcess_Exited(object sender, System.EventArgs e)
{
    inProcess = false;
    Console.WriteLine("Exit time:    {0}\r\n" +
      "Exit code:    {1}\r\n", proc.ExitTime, proc.ExitCode);
}

Насправді не відповідає на питання. Будь ласка, уточнюйте свою відповідь, щоб вирішити питання
Грантлі

А зараз? можливо, відкрийте vb і прийміть рішення;)
Девід Лопес

-5

Спробуйте це:

string command = "...";
var process = Process.Start(command);
process.WaitForExit();

5
Який сенс коментувати відповідь на вже відповів на питання, на яке вже відповіли? Ви не тільки витратили свої власні цикли, але й змусили мене також витрачати мій.
Джеймі Іванов

@AdamBilinski питання та відповіді призначені для того, щоб їх бачили інші люди, які мають запитання не лише у того, хто задав питання
L3n

4
@ L3n Я згоден, але ця відповідь точно така ж, як і прийнята відповідь, тому безглуздо!
Адам Білінський

@AdamBilinski О, я не прочитав ваш коментар належним чином пробачте мені xD
L3n
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.