我需要确定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。提前谢谢。
答案 0 :(得分:2)
SERVICE_STATUS_PROCESS
结构中返回的进程标识符有效,前提是该服务的状态是SERVICE_RUNNING
,SERVICE_PAUSE_PENDING
,SERVICE_PAUSED
或{{1}之一}。但是,如果服务处于SERVICE_CONTINUE_PENDING
或SERVICE_START_PENDING
状态,则进程标识符可能无效,如果服务处于SERVICE_STOP_PENDING
状态,则它永远不会有效。
仅仅因为您可以获得服务的SERVICE_STOPPED
句柄并不能保证服务实际上正在运行。 SC_SERVICE
会在QueryServiceStatus/Ex()
字段中告诉您服务是否正在运行。
您在第一次dwCurrentState
来电时也没有进行任何错误处理。
尝试更像这样的事情:
QueryServiceStatusEx()