Saltar al contenido

Obtener el PID de un servicio de Windows

Te damos la bienvenida a nuestro espacio, en este sitio hallarás la resolución que estabas buscando.

Solución:

Lo que las otras respuestas descuidan es el hecho de que un proceso único también puede albergar múltiples servicios autónomos. Las múltiples instancias de la svchost.exe proceso, cada uno de los cuales alberga un par de servicios, es el mejor ejemplo.

Entonces, en general, es absolutamente inseguro intentar eliminar un servicio arbitrario eliminando su proceso de alojamiento (supongo que eso es lo que intenta hacer, ya que se refiere a taskkill.exe). Puede eliminar varios servicios no relacionados en el proceso.

Si sabe que el proceso del servicio solo aloja el servicio que le interesa, entonces puede elegir la estrategia sugerida por @MC en su respuesta.

Como alternativa, también puede usar la clase ServiceController para abrir un identificador de su servicio y luego usarlo (a través de la propiedad ServiceHandle) para P/Invocar la función QueryServiceStatusEx para averiguar el ID de proceso que desea conocer.

Si necesita más detalles, debe aclarar qué es lo que está en realidad tratando de lograr. No está claro en tu pregunta.

Actualizar Aquí hay un código que saqué de un proyecto existente que debería hacer lo que quieras, dado que tienes un ServiceController instancia. _Como se dijo anteriormente, ¡úselo con cuidado!__

[StructLayout(LayoutKind.Sequential)]
internal sealed class SERVICE_STATUS_PROCESS

    [MarshalAs(UnmanagedType.U4)]
    public uint dwServiceType;
    [MarshalAs(UnmanagedType.U4)]
    public uint dwCurrentState;
    [MarshalAs(UnmanagedType.U4)]
    public uint dwControlsAccepted;
    [MarshalAs(UnmanagedType.U4)]
    public uint dwWin32ExitCode;
    [MarshalAs(UnmanagedType.U4)]
    public uint dwServiceSpecificExitCode;
    [MarshalAs(UnmanagedType.U4)]
    public uint dwCheckPoint;
    [MarshalAs(UnmanagedType.U4)]
    public uint dwWaitHint;
    [MarshalAs(UnmanagedType.U4)]
    public uint dwProcessId;
    [MarshalAs(UnmanagedType.U4)]
    public uint dwServiceFlags;


internal const int ERROR_INSUFFICIENT_BUFFER = 0x7a;
internal const int SC_STATUS_PROCESS_INFO = 0;

[DllImport("advapi32.dll", SetLastError = true)]
internal static extern bool QueryServiceStatusEx(SafeHandle hService, int infoLevel, IntPtr lpBuffer, uint cbBufSize, out uint pcbBytesNeeded);

public static int GetServiceProcessId(this ServiceController sc)

    if (sc == null)
        throw new ArgumentNullException("sc");

    IntPtr zero = IntPtr.Zero;

    try
    
        UInt32 dwBytesNeeded;
        // Call once to figure the size of the output buffer.
        QueryServiceStatusEx(sc.ServiceHandle, SC_STATUS_PROCESS_INFO, zero, 0, out dwBytesNeeded);
        if (Marshal.GetLastWin32Error() == ERROR_INSUFFICIENT_BUFFER)
        
            // Allocate required buffer and call again.
            zero = Marshal.AllocHGlobal((int)dwBytesNeeded);

            if (QueryServiceStatusEx(sc.ServiceHandle, SC_STATUS_PROCESS_INFO, zero, dwBytesNeeded, out dwBytesNeeded))
            
                var ssp = new SERVICE_STATUS_PROCESS();
                Marshal.PtrToStructure(zero, ssp);
                return (int)ssp.dwProcessId;
            
        
    
    finally
    
        if (zero != IntPtr.Zero)
        
            Marshal.FreeHGlobal(zero);
        
    
    return -1;

Suponiendo que conoce el nombre del EXE que utiliza el servicio y hay exactamente uno de ellos:

int procID = Process.GetProcessesByName("yourservice")[0].Id;

El método Process.GetProcessesByName("yourservice") devuelve una matriz de procesos con su nombre especificado, por lo que en caso de que no sepa cuántos de "yourservice.exe" se ejecuta simultáneamente, es posible que necesite un bucle foreach.

Vea esta respuesta en una pregunta similar: Averiguar el nombre del proceso en ejecución del servicio de Windows

Usando una consulta WMI puede:

Encuentre todos los servicios relacionados con un solo exe (un solo exe puede alojar múltiples servicios):

select Name from Win32_Service where ProcessId = 588

O, para responder a esta pregunta, puede obtener el PID del proceso en el que se ejecuta un servicio:

select ProcessId from Win32_Service where Name = 'wuauserv'

Si aceptas, tienes el poder dejar un artículo acerca de qué le añadirías a este tutorial.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *