为什么运行Windows服务的进程ID为零(QueryServiceStatusEx)?

时间:2016-06-16 16:32:11

标签: c winapi service pid

我需要确定Windows服务的进程ID(我正在使用C)。看到我有权访问服务的SC_HANDLE,QueryServiceStatusEx正是我需要的功能。但是,当访问SERVICE_STATUS_PROCESS返回的QueryServiceStatusEx结构中的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中列出的PID相匹配。

我很遗憾dwProcessId字段为什么包含0,显然不能是有效的PID。提前谢谢。

1 个答案:

答案 0 :(得分:2)

根据QueryServiceStatusEx()文档:

  

SERVICE_STATUS_PROCESS结构中返回的进程标识符有效,前提是该服务的状态是SERVICE_RUNNINGSERVICE_PAUSE_PENDINGSERVICE_PAUSED或{{1}之一}。但是,如果服务处于SERVICE_CONTINUE_PENDINGSERVICE_START_PENDING状态,则进程标识符可能无效,如果服务处于SERVICE_STOP_PENDING状态,则它永远不会有效。

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

您在第一次dwCurrentState来电时也没有进行任何错误处理。

尝试更像这样的事情:

QueryServiceStatusEx()