Aguarde até que um processo termine

206

Eu tenho um aplicativo que faz

Process.Start()

para iniciar outra aplicação 'ABC'. Eu quero esperar até que o aplicativo termine (processo acabe) e continue minha execução. Como eu posso fazer isso?

Pode haver várias instâncias do aplicativo 'ABC' sendo executadas ao mesmo tempo.

NLV
fonte
E se você quiser fazer isso de forma assíncrona (ou seja, gerar um evento após a conclusão), você pode olhar aqui no SO.
Matt

Respostas:

401

Eu acho que você só quer isso:

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

Veja a página do MSDN para o método Ele também possui uma sobrecarga na qual é possível especificar o tempo limite, para que você não esteja potencialmente esperando para sempre.

Noldorin
fonte
137

Usar Process.WaitForExit? Ou inscreva-se no Process.Exitedevento se você não deseja bloquear? Se isso não fizer o que você deseja, forneça mais informações sobre seus requisitos.

Jon Skeet
fonte
boas informações definitivamente com Process.Exited, mas o OP disse "esperar"
Mike M
8
@MikeM: É por isso que me referi WaitForExitprimeiro ... em alguns casos, você pode querer executar mais código quando algo terminar, mas isso não significa que você precise bloquear o segmento atual.
Jon Skeet
7
Se você for usar o Process.Exitedevento, acredito que você deve configurar o processo antecipadamente, definindo Process.EnableRaisingEventscomo true. No entanto, considerando que essa pergunta tem mais de três anos, pode ser que isso Process.EnableRaisingEventsnão tenha acontecido no momento em que foi feita.
Será
Acabei nesta página procurando o nome do Process.Exitedevento. Obrigado! +1 para completar
Chad
36

Eu faço o seguinte no meu aplicativo:

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.

Existem alguns recursos extras que você pode achar úteis ...

AnthonyLambert
fonte
17

Você pode usar aguardar a saída ou capturar a propriedade HasExited e atualizar sua interface do usuário para manter o usuário "informado" (gerenciamento de expectativas):

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

Eu tive um caso em Process.HasExitedque não mudou depois de fechar a janela pertencente ao processo. Então Process.WaitForExit()também não funcionou. Eu tive que monitorar Process.Respondingque foi falso depois de fechar a janela assim:

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

Talvez isso ajude alguém.

Buka
fonte
6

Process.WaitForExit deve ser exatamente o que você está procurando, eu acho.

Hans Olsson
fonte
1

Referindo-se ao exemplo da Microsoft: [ https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.process.enableraisingevents?view=netframework-4.8]

O melhor seria definir:

myProcess.EnableRaisingEvents = true;

Caso contrário, o Código será bloqueado. Também não são necessárias propriedades adicionais.

// 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}");
}
Julian
fonte
0

Como Jon Skeet diz, use o 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);
}
David Lopes
fonte
Realmente não responde à pergunta. Por favor, refine sua resposta para resolver a questão #
Grantly
E agora? talvez vb aberto e fazer a solução;)
David Lopes
-5

Tente o seguinte:

string command = "...";
var process = Process.Start(command);
process.WaitForExit();
user3065161
fonte
5
Qual o sentido de comentar uma resposta a uma pergunta já respondida sobre a pergunta já respondida? Você não apenas desperdiçou seus próprios ciclos, mas também me obrigou a desperdiçar o meu.
Jamie Ivanov
Perguntas e respostas @AdamBilinski se destinam a ser visto por outras pessoas que têm a questão não só a quem perguntou
L3n
4
@ L3n Eu concordo, mas esta resposta é exatamente a mesma que a resposta aceita, por isso é inútil!
Adam Bilinski
@AdamBilinski Oh sim, não leu seu comentário corretamente me perdoe xD
L3n 24/07/2015