Get the PID of a Windows service

后端 未结 3 1396
星月不相逢
星月不相逢 2021-02-19 03:37

Could anyone help me to know how to get the PID of a Windows service?
I need to get the PID in order to run the following command:

Process.Start(new Process         


        
3条回答
  •  执念已碎
    2021-02-19 04:03

    What the other answers neglect is the fact that a single process can also host multiple, autonomous services. The multiple instances of the svchost.exe process, each hosting a couple of services, is the best example.

    So in general, it is absolutely unsafe to try to kill an arbitrary service by killing it's hosting process (I assume that is what you attempt to do, since you refer to taskkill.exe). You might take down several unrelated services in the process.

    If you do know that the service's process only hosts the service you care about, than you can choose the strategy as suggested by @M C in his/her answer.

    Alternatively, you can also use the ServiceController class to open a handle to your service and then use it (via the ServiceHandle property) to P/Invoke the QueryServiceStatusEx function to find out the Process ID you want to know.

    If you need more details, you should clarify what it is that you're actually trying to achieve. It is not clear from your question.

    Update Here is some code I ripped out of an existing project that should do what you want, given you have a ServiceController instance. _As said above, use with care!__

    [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;
    }
    

提交回复
热议问题