c# - Averiguar el nombre de proceso de ejecución del servicio de Windows.NET 1.1
windows-services process (6)
Estamos utilizando un servicio de Windows mal escrito, que se bloqueará cuando intentemos detenerlo desde el código. Entonces, necesitamos encontrar qué proceso está relacionado con ese servicio y matarlo. ¿Alguna sugerencia?
Microsoft / SysInternals tiene una herramienta de línea de comandos llamada PsKill que le permite matar un proceso por su nombre. Esta herramienta también le permite eliminar procesos en otros servidores. Windows SysInternals
Uso: pskill [-t] [/ computer [-u username [-p password]]] <ID del proceso | nombre>
-t Matar el proceso y sus descendientes.
-u Especifica el nombre de usuario opcional para iniciar sesión en la computadora remota.
-p Especifica la contraseña opcional para el nombre de usuario. Si omite esto, se le pedirá que ingrese una contraseña oculta.
Puedes usar
tasklist /svc /fi "SERVICES eq YourServiceName"
Para encontrar el nombre del proceso y la identificación, y también si el mismo proceso aloja otros servicios.
Supongo que es un proceso de dos pasos: si siempre es el mismo servicio, puede encontrar fácilmente el nombre del proceso utilizando los métodos sugeridos en otras respuestas.
Luego tengo el siguiente código en una clase en un servidor web .NET 1.1:
Process[] runningProcs =
Process.GetProcessesByName("ProcessName");
foreach (Process runningProc in runningProcs)
{
// NOTE: Kill only works for local processes
runningProc.Kill();
}
El método Kill puede arrojar algunas excepciones que debería considerar capturar, especialmente la Win32Exception, que se lanza si no se puede eliminar el proceso.
Tenga en cuenta que el método WaitForExit y la propiedad HasExited también existen en el mundo 1.1, pero no se mencionan en la página de documentación para Kill in 1.1.
WMI tiene esta información: la clase Win32_Service.
Una consulta WQL como
SELECT ProcessId FROM Win32_Service WHERE Name=''MyServiceName''
usando System.Management debería hacer el truco.
Desde un vistazo rápido, vea: taskllist.exe /svc
y otras herramientas desde la línea de comandos.
Para responder exactamente a mi pregunta: cómo encontrar el Proceso relacionado con algún servicio:
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
}
}
}
Puede usar System.Management.MangementObjectSearcher
para obtener la ID de proceso de un servicio y System.Diagnostics.Process
para obtener la instancia de Process
correspondiente y eliminarla.
El método KillService()
en el siguiente programa muestra cómo hacer esto:
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.
}
}
}
}
}