Como posso saber se um processo está sendo executado?

Quando obtenho uma referência a um System.Diagnostics.Process , como posso saber se um processo está sendo executado atualmente?

Esta é uma maneira de fazer isso com o nome:

 Process[] pname = Process.GetProcessesByName("notepad"); if (pname.Length == 0) MessageBox.Show("nothing"); else MessageBox.Show("run"); 

Você pode fazer o loop de todo o processo para obter o ID para posterior manipulação:

 Process[] processlist = Process.GetProcesses(); foreach(Process theprocess in processlist){ Console.WriteLine("Process: {0} ID: {1}", theprocess.ProcessName, theprocess.Id); } 

Essa é a maneira mais simples que encontrei depois de usar o refletor. Eu criei um método de extensão para isso:

 public static class ProcessExtensions { public static bool IsRunning(this Process process) { if (process == null) throw new ArgumentNullException("process"); try { Process.GetProcessById(process.Id); } catch (ArgumentException) { return false; } return true; } } 

O método Process.GetProcessById(processId) chama o método ProcessManager.IsProcessRunning(processId) e lança ArgumentException no caso do processo não existir. Por algum motivo, a class ProcessManager é interna …

Solução síncrona:

 void DisplayProcessStatus(Process process) { process.Refresh(); // Important if(process.HasExited) { Console.WriteLine("Exited."); } else { Console.WriteLine("Running."); } } 

Solução assíncrona:

 void RegisterProcessExit(Process process) { // NOTE there will be a race condition with the caller here // how to fix it is left as an exercise process.Exited += process_Exited; } static void process_Exited(object sender, EventArgs e) { Console.WriteLine("Process has exited."); } 

reshefm teve uma resposta bem legal; no entanto, não leva em conta uma situação na qual o processo nunca foi iniciado para começar.

Aqui está uma versão modificada do que ele postou.

  public static bool IsRunning(this Process process) { try {Process.GetProcessById(process.Id);} catch (InvalidOperationException) { return false; } catch (ArgumentException){return false;} return true; } 

Eu removi seu ArgumentNullException porque na verdade ele supõe ser uma exceção de referência nula e ele é lançado pelo sistema de qualquer maneira e eu também levei em conta a situação na qual o processo nunca foi iniciado ou o método close () foi usado para fechar o processo.

Este deve ser um one-liner:

 public static class ProcessHelpers { public static bool IsRunning (string name) => Process.GetProcessesByName(name).Length > 0; } 

Depende de quão confiável você quer que esta function seja. Se você quiser saber se a instância de processo específica que você tem ainda está em execução e disponível com 100% de precisão, você está sem sorte. A razão é que, a partir do object de processo gerenciado, existem apenas duas maneiras de identificar o processo.

O primeiro é o ID do processo. Infelizmente, os IDs de processo não são exclusivos e podem ser reciclados. Pesquisar na lista de processos por um Id correspondente apenas informa que existe um processo com o mesmo ID em execução, mas não é necessariamente o seu processo.

O segundo item é o identificador de processo. Tem o mesmo problema que o Id e é mais complicado trabalhar com ele.

Se você está procurando confiabilidade de nível médio, verificar a lista de processos atual para um processo com o mesmo ID é suficiente.

Process.GetProcesses() é o caminho a percorrer. Mas você pode precisar usar um ou mais critérios diferentes para encontrar o seu processo, dependendo de como ele está sendo executado (ou seja, como um serviço ou um aplicativo normal, com ou sem uma barra de título).

Talvez (provavelmente) eu esteja lendo a questão de forma errada, mas você está procurando a propriedade HasExited que lhe dirá que o processo representado pelo seu object Process foi encerrado (normalmente ou não).

Se o processo para o qual você tem uma referência tiver uma interface do usuário, você poderá usar a propriedade Respondendo para determinar se a interface do usuário está respondendo à input do usuário ou não.

Você também pode definir EnableRaisingEvents e manipular o evento Exited (que é enviado asychronously) ou chamar WaitForExit () se você deseja bloquear.

Você pode instanciar uma instância de processo uma vez para o processo que deseja e continuar rastreando o processo usando esse object .NET Process (ele continuará rastreando até você chamar explicitamente esse object .NET explicitamente, mesmo que o processo que ele rastreou tenha morrido) [isto é para poder dar-lhe tempo de processo próximo, também conhecido como ExitTime etc.])

Citando http://msdn.microsoft.com/pt-br/library/fb4aw7b8.aspx :

Quando um processo associado é encerrado (ou seja, quando é encerrado pelo sistema operacional por meio de uma finalização normal ou anormal), o sistema armazena informações administrativas sobre o processo e retorna ao componente que chamou WaitForExit. O componente de processo pode acessar as informações, que inclui o ExitTime, usando o identificador para o processo de saída.

Como o processo associado foi encerrado, a propriedade Handle do componente não aponta mais para um recurso de processo existente. Em vez disso, o identificador pode ser usado apenas para acessar as informações do sistema operacional sobre o recurso do processo. O sistema está ciente de identificadores para processos que não foram liberados pelos componentes do processo, portanto, ele mantém as informações de ExitTime e identificador na memory até que o componente de processo especificamente libera os resources. Por esse motivo, sempre que você chamar a instância Start for Process, chame Close quando o processo associado tiver terminado e você não precisar mais de nenhuma informação administrativa sobre ele. Close libera a memory alocada para o processo finalizado.

Eu tentei a solução da Coincoin:
Antes de processar algum arquivo, copio-o como um arquivo temporário e abro-o.
Quando terminar, fecho o aplicativo se ele ainda estiver aberto e excluo o arquivo temporário:
Acabei de usar uma variável de processo e verifique depois:

 private Process openApplication; private void btnOpenFile_Click(object sender, EventArgs e) { ... // copy current file to fileCache ... // open fileCache with proper application openApplication = System.Diagnostics.Process.Start( fileCache ); } 

Mais tarde fecho o aplicativo:

  ... openApplication.Refresh(); // close application if it is still open if ( !openApplication.HasExited() ) { openApplication.Kill(); } // delete temporary file System.IO.File.Delete( fileCache ); 

Funciona (até agora)

  string process="notepad"; if (Process.GetProcessesByName(process).Length == 0) { MessageBox.Show("Working"); } else { MessageBox.Show("Not Working"); } 

também você pode usar um timer para verificar o processo toda vez

Apesar da API suportada de frameworks .Net em relação à verificação do processo existente por ID do processo, essas funções são muito lentas. Custa uma quantidade enorme de ciclos de CPU para executar Process.GetProcesses () ou Process.GetProcessById / Name ().

Um método muito mais rápido para verificar um processo em execução por ID é usar o API OpenProcess () nativo. Se o identificador de retorno for 0, o processo não existe. Se handle for diferente de 0, o processo está sendo executado. Não há garantia de que esse método funcionaria 100% a todo momento devido à permissão.