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.


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.


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.


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 ...


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

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.



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}");
}

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);
}

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();

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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.