Descobrindo o nome do processo em execução do serviço do Windows .NET 1.1

Estamos usando um serviço do Windows mal escrito, que irá travar quando estamos tentando pará-lo do código. Portanto, precisamos descobrir qual processo está relacionado a esse serviço e eliminá-lo. Alguma sugestão?

WMI tem essa informação: a class Win32_Service.

Uma consulta WQL como

SELECT ProcessId FROM Win32_Service WHERE Name='MyServiceName' 

Usando System.Management deve fazer o truque.

De uma olhada rápida veja: taskllist.exe /svc e outras ferramentas da linha de comando.

Você pode usar System.Management.MangementObjectSearcher para obter o ID do processo de um serviço e System.Diagnostics.Process para obter a instância do Process correspondente e eliminá-la.

O método KillService() no programa a seguir mostra como fazer isso:

 using System; using System.ComponentModel; using System.Diagnostics; using System.Management; namespace KillProcessApp { class Program { static void Main(string[] args) { KillService("YourServiceName"); } static void KillService(string serviceName) { string query = string.Format( "SELECT ProcessId FROM Win32_Service WHERE Name='{0}'", serviceName); ManagementObjectSearcher searcher = new ManagementObjectSearcher(query); foreach (ManagementObject obj in searcher.Get()) { uint processId = (uint) obj["ProcessId"]; Process process = null; try { process = Process.GetProcessById((int)processId); } catch (ArgumentException) { // Thrown if the process specified by processId // is no longer running. } try { if (process != null) { process.Kill(); } } catch (Win32Exception) { // Thrown if process is already terminating, // the process is a Win16 exe or the process // could not be terminated. } catch (InvalidOperationException) { // Thrown if the process has already terminated. } } } } } 

Você pode usar

 tasklist /svc /fi "SERVICES eq YourServiceName" 

Para encontrar o nome e id do processo, e também se o mesmo processo hospeda outros serviços.

Para responder exatamente a minha pergunta – como encontrar o processo relacionado a algum serviço:

 ManagementObjectSearcher searcher = new ManagementObjectSearcher ("SELECT * FROM Win32_Service WHERE DisplayName = '" + serviceName + "'"); foreach( ManagementObject result in searcher.Get() ) { if (result["DisplayName"].ToString().ToLower().Equals(serviceName.ToLower())) { int iPID = Convert.ToInt32( result["ProcessId"] ); KillProcessByID(iPID, 1000); //some method that will kill Process for given PID and timeout. this should be trivial } } 

}

Microsoft / SysInternals tem uma ferramenta de linha de comando chamada PsKill que permite que você mate um processo pelo nome. Essa ferramenta também permite que você mate processos em outros servidores. Windows SysInternals

Uso: pskill [-t] [\ computador [-u username [-p password]]]
-t Mate o processo e seus descendentes.
-u Especifica o nome de usuário opcional para login no computador remoto.
-p Especifica a senha opcional para o nome do usuário. Se você omitir isso, você será solicitado a digitar uma senha oculta.

Eu acho que é um processo de duas etapas – se é sempre o mesmo serviço, você pode facilmente encontrar o nome do processo usando methods sugeridos em outras respostas.

Eu tenho então o seguinte código em uma class em um servidor da Web .NET 1.1:

 Process[] runningProcs = Process.GetProcessesByName("ProcessName"); foreach (Process runningProc in runningProcs) { // NOTE: Kill only works for local processes runningProc.Kill(); } 

O método Kill pode lançar algumas exceções que você deve considerar capturar – especialmente o Win32Exception, que é acionado se o processo não pode ser morto.

Observe que o método WaitForExit e a propriedade HasExited também existem no mundo 1.1, mas não são mencionados na página de documentação do Kill em 1.1.