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.