c# - 获取 Windows 服务的 PID

标签 c# .net windows-services

谁能帮我知道如何获取Windows服务的PID?
我需要获取 PID 才能运行以下命令:

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

最佳答案

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

因此,一般来说,尝试通过终止托管进程来终止任意服务是绝对不安全的(我假设这就是您尝试执行的操作,因为您引用了 taskkill.exe)。您可能会在此过程中取消几个不相关的服务。

如果您确实知道该服务的进程仅托管您关心的服务,那么您可以选择@MC 在他/她的回答中建议的策略。

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

如果您需要更多详细信息,您应该阐明您实际想要实现的目标。从你的问题中不清楚。

更新 这是我从现有项目中提取的一些代码,如果您有一个 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;
}

关于c# - 获取 Windows 服务的 PID,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23084720/

相关文章:

.net - WiX - 安装 Windows 服务并授予权限

c# - 创建自定义 TreeView/TreeNode

c# - 如何获得具有不同背景颜色的下拉菜单。下拉选项是动态的

c# - C# 中的 LINQ 查询使用动态字符串来 ORDER 数据

c# - 当控制台应用程序使用完全相同的基础库执行完全相同的事情时,什么会导致 Windows 服务挂起?

c# - 用 c# .NET 4 vs2010 编写的 Windows 服务不会安装在 Server 2008 R2 Enterprise 上

C# WinRT 类型类缺少函数

c# - 用于更改可为空和非空数据类型的数据注释是什么?

c# - 从 Windows 桌面应用程序发送电子邮件错误报告

c# - Xpath 命名空间解析