【问题标题】:Why is process ID of running Windows services zero (QueryServiceStatusEx)?为什么运行 Windows 服务的进程 ID 为零(QueryServiceStatusEx)?
【发布时间】:2023-03-09 16:15:01
【问题描述】:

我需要确定 Windows 服务的进程 ID(我正在使用 C)。鉴于我可以访问服务的 SC_HANDLE,QueryServiceStatusEx 正是我需要的功能。但是,当访问QueryServiceStatusEx返回的SERVICE_STATUS_PROCESS结构中的dwProcessId字段时,它包含0。 这是我的代码:

unsigned int get_svc_pid (SC_HANDLE svc) {

    unsigned int pid = 0;
    BYTE *svc_info = NULL;
    DWORD buf_size = 0;
    DWORD bytes_needed = 0;
    //determine svc_info size
    QueryServiceStatusEx(svc, SC_STATUS_PROCESS_INFO, svc_info, buf_size, &bytes_needed);
    svc_info = malloc(bytes_needed);
    buf_size = bytes_needed;
    //get pid
    if(QueryServiceStatusEx(svc, SC_STATUS_PROCESS_INFO, svc_info, buf_size, &bytes_needed) != 0){
        pid = (*(SERVICE_STATUS_PROCESS *)svc_info).dwProcessId;
    }else{
        fprintf(msglog, "ERR: QueryServiceStatusEx failed\nGLE: %u\n", (unsigned int) GetLastError());
    }
    free(svc_info);
    return pid;
}

另外:我使用EnumServiceStatusEx 枚举所有正在运行的服务并输出它们的名称和包含在ENUM_SERVICE_STATUS_PROCESS 结构中的PID。大多数 PID 为 0。结构中只有少数 PID 与 ProcessHacker/TaskManager 中列出的那些匹配。

我不知道为什么 dwProcessId 字段包含 0,但显然这不是有效的 PID。提前谢谢你。

【问题讨论】:

  • 因为那些服务没有运行

标签: c winapi service pid


【解决方案1】:

根据QueryServiceStatusEx() 文档:

如果服务的状态是SERVICE_RUNNINGSERVICE_PAUSE_PENDINGSERVICE_PAUSEDSERVICE_CONTINUE_PENDING 之一,则SERVICE_STATUS_PROCESS 结构中返回的进程标识符是有效的。但是,如果服务处于SERVICE_START_PENDINGSERVICE_STOP_PENDING 状态,则进程标识符可能无效,如果服务处于SERVICE_STOPPED 状态,则它永远不会有效。

仅仅因为您可以获得服务的SC_SERVICE 句柄并不能保证该服务实际上正在运行。 QueryServiceStatus/Ex()dwCurrentState 字段中告诉您服务是否正在运行。

您也没有对第一次QueryServiceStatusEx() 调用进行任何错误处理。

试试这样的:

unsigned int get_svc_pid (SC_HANDLE svc)
{
    DWORD pid = 0;
    BYTE *buf = NULL;
    DWORD buf_size = 0;
    SERVICE_STATUS_PROCESS *svc_info = NULL;

    //determine svc_info size
    QueryServiceStatusEx(svc, SC_STATUS_PROCESS_INFO, NULL, 0, &buf_size);
    if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
    {
        fprintf(msglog, "ERR: QueryServiceStatusEx failed\nGLE: %u\n", GetLastError());
        return 0;
    }

    buf = malloc(buf_size);
    if (!buf)
    {
        fprintf(msglog, "ERR: malloc failed\nsize requested: %u\n", buf_size);
        return 0;
    }

    //get pid
    if (!QueryServiceStatusEx(svc, SC_STATUS_PROCESS_INFO, buf, buf_size, &buf_size))
    {
        fprintf(msglog, "ERR: QueryServiceStatusEx failed\nGLE: %u\n", GetLastError());
    }
    else
    {
        svc_info = (SERVICE_STATUS_PROCESS*) buf;
        switch (svc_info->dwCurrentState)
        {
            case SERVICE_RUNNING:
            case SERVICE_PAUSE_PENDING:
            case SERVICE_PAUSED:
            case SERVICE_CONTINUE_PENDING:
                pid = svc_info->dwProcessId;
                break;
        }
    }

    free(buf);
    return pid;
}

【讨论】:

    猜你喜欢
    • 2011-01-17
    • 2021-10-18
    • 1970-01-01
    • 2012-01-14
    • 1970-01-01
    • 2013-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多