Encontrar todos os processos filhos do meu próprio processo .NET / descobrir se um determinado processo é um filho meu?

Eu tenho uma biblioteca de classs .NET que gira um processo secundário que é mantido em execução até que eu descarte o object.

Devido a algumas ocorrências do programa permanecerem na memory, decidi adicionar um teste de integração para garantir que, se eu deixar o object passar para o GC / Finalização, esse processo será desativado.

No entanto, como o processo é o cliente de linha de comando do Mercurial e meu servidor de compilation já está executando o Mercurial como parte de suas próprias operações, imagino situações em que o Mercurial já esteja em execução quando o teste for iniciado ou iniciado e ainda correndo, quando o teste termina, em relação ao servidor de compilation, e não ao meu teste.

Então, eu quero ter certeza de que o cliente Mercurial que eu acho (ou não) é o que eu iniciei, e não apenas qualquer cliente que esteja atualmente rodando.

Então a questão é esta:

  • Como posso saber se o cliente Mercurial que estou olhando foi iniciado pelo meu processo?

Por “olhando”, eu estava olhando para usar o método Process.GetProcesses , mas isso não é um requisito.

Se uma pergunta diferente é melhor, “Como encontrar todos os processos filhos do meu próprio processo”, ou seja. mais fácil de responder, que é mais do que suficiente também.

Eu encontrei esta página: Como posso saber o ID do processo pai de um processo? , mas parece que eu tenho que dar o nome do processo. Se eu der apenas “hg”, essa pergunta não é tão ambígua para o caso que estou procurando?

Quando isso acontece, eu tenho um código C # / WMI que mata todos os processos gerados por um id de processo especificado, de forma recursiva. a matança obviamente não é o que você quer, mas a descoberta de processos infantis parece ser o que você está interessado. Espero que isso seja útil:

private static void KillAllProcessesSpawnedBy(UInt32 parentProcessId) { logger.Debug("Finding processes spawned by process with Id [" + parentProcessId + "]"); // NOTE: Process Ids are reused! ManagementObjectSearcher searcher = new ManagementObjectSearcher( "SELECT * " + "FROM Win32_Process " + "WHERE ParentProcessId=" + parentProcessId); ManagementObjectCollection collection = searcher.Get(); if (collection.Count > 0) { logger.Debug("Killing [" + collection.Count + "] processes spawned by process with Id [" + parentProcessId + "]"); foreach (var item in collection) { UInt32 childProcessId = (UInt32)item["ProcessId"]; if ((int)childProcessId != Process.GetCurrentProcess().Id) { KillAllProcessesSpawnedBy(childProcessId); Process childProcess = Process.GetProcessById((int)childProcessId); logger.Debug("Killing child process [" + childProcess.ProcessName + "] with Id [" + childProcessId + "]"); childProcess.Kill(); } } } } 

Embora a resposta de mtijn seja provavelmente a mais próxima que você pode gerar, a verdadeira resposta é: você não pode.

O Windows não mantém uma tree de processos real em que os processos são reestruturados quando um processo em um nível intermediário é interrompido. No entanto, o Windows se lembra do ID do processo pai.

O caso problemático é o seguinte:

Estrutura do processo original:

 YourApp.exe - SubApp.exe - Second.exe 

Se agora SubApp.exe terminar, o ID do processo pai do Second.exe não será atualizado. O novo resultado é

 YourApp.exe Second.exe 

Você pode verificar isso usando o SysInternals Process Explorer. É capaz de mostrar os processos como uma tree. Inicie o CMD e digite start cmd . Na nova janela, digite start cmd novamente. Você terá 3 janelas abertas. Agora termine o do meio.