获取Windows服务的PID

本文关键字:PID 服务 Windows 获取 | 更新日期: 2023-09-27 17:58:36

有人能帮我了解如何获取Windows服务的PID吗
我需要获取PID才能运行以下命令:

Process.Start(new ProcessStartInfo 
    {
        Filename = "cmd.exe",
        CreateNoWindow = true,
        UseShellExecute = false,
        Arguments = string.Format("/c taskkill /pid {0} /f", pidnumber)
    });

获取Windows服务的PID

其他答案忽略了一个事实,即单个进程也可以托管多个自治服务svchost.exe进程的多个实例就是最好的例子,每个实例都托管着几个服务。

因此,一般来说,试图通过杀死任意服务的托管进程来杀死它是绝对不安全的(我认为这就是你想要做的,因为你指的是taskkill.exe)。在此过程中,您可能会删除几个不相关的服务。

如果你知道服务的流程只托管你关心的服务,那么你可以选择@MC在他/她的回答中建议的策略。

或者,您也可以使用ServiceController类打开服务的句柄,然后使用它(通过ServiceHandle属性)p/Invoke QueryServiceStatusEx函数来查找您想要知道的进程ID。

如果你需要更多的细节,你应该澄清你实际上试图实现的是什么。你的问题不清楚。

Update以下是我从现有项目中提取的一些代码,如果您有一个ServiceController实例,这些代码应该可以做您想要的事情_如上所述,小心使用!__

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

请参阅类似问题的答案:查找Windows服务的运行进程名称

使用WMI查询可以-

查找与单个exe相关的所有服务(单个exe可以承载多个服务):

select Name from Win32_Service where ProcessId = 588

或者,为了回答这个问题,您可以获得服务运行的进程的PID:

select ProcessId from Win32_Service where Name = 'wuauserv'

假设您知道服务使用的EXE的名称,则只有其中一个:

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

方法Process.GetProcessesByName("yourservice")返回一个具有指定名称的进程数组,因此,如果您不知道有多少"yourservice.exe"同时运行,则可能需要foreach循环。