Получить PID службы Windows

Может ли кто-нибудь помочь мне узнать, как получить PID службы Windows?
Мне нужно получить PID, чтобы выполнить следующую команду:

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

Ответ 1

Предполагая, что вы знаете имя EXE файла, который использует сервис, и есть только один из них:

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

Метод Process.GetProcessesByName("yourservice") возвращает массив процессов с указанным именем, поэтому в случае, если вы не знаете, сколько "yourservice.exe" выполняется одновременно, вам может понадобиться цикл foreach.

Ответ 2

То, что другие ответы игнорируют, заключается в том, что одиночный процесс также может содержать несколько автономных сервисов. Наилучшим примером является несколько экземпляров процесса svchost.exe, каждый из которых содержит несколько сервисов.

В общем, абсолютно небезопасно пытаться убить произвольную службу, убив ее хостинг-процесс (я предполагаю, что это то, что вы пытаетесь сделать, поскольку вы ссылаетесь на taskkill.exe). В этом процессе вы можете удалить несколько несвязанных сервисов.

Если вы знаете, что сервисный процесс обслуживает только тот сервис, который вам интересен, вы можете выбрать стратегию, предложенную @M C в его/ее ответе.

В качестве альтернативы вы также можете использовать класс ServiceController, чтобы открыть дескриптор вашей службы, а затем использовать его (через ServiceHandle) P/Invoke QueryServiceStatusEx, чтобы узнать идентификатор процесса, который вы хотите узнать.

Если вам нужна дополнительная информация, вы должны уточнить, что именно вы пытаетесь достичь. Это не ясно из вашего вопроса.

Обновление. Вот код, который я вырвал из существующего проекта, который должен делать то, что вы хотите, учитывая, что у вас есть экземпляр 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;
}

Ответ 3

См. ответ на аналогичный вопрос: Поиск имени выполняемого процесса службы Windows

С помощью запроса WMI вы можете -

Найти все службы, связанные с одним exe (один exe может принимать несколько сервисов):

select Name from Win32_Service where ProcessId = 588

Или, чтобы ответить на этот вопрос, вы можете получить PID процесса, в котором работает служба:

select ProcessId from Win32_Service where Name = 'wuauserv'