为什么 运行 Windows 服务的进程 ID 为零 (QueryServiceStatusEx)?
Why is process ID of running Windows services zero (QueryServiceStatusEx)?
我需要确定 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。提前谢谢你。
根据 QueryServiceStatusEx()
文档:
The process identifier returned in the SERVICE_STATUS_PROCESS
structure is valid provided that the state of the service is one of SERVICE_RUNNING
, SERVICE_PAUSE_PENDING
, SERVICE_PAUSED
, or SERVICE_CONTINUE_PENDING
. If the service is in a SERVICE_START_PENDING
or SERVICE_STOP_PENDING
state, however, the process identifier may not be valid, and if the service is in the SERVICE_STOPPED
state, it is never valid.
仅仅因为您可以获得服务的 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;
}
我需要确定 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。提前谢谢你。
根据 QueryServiceStatusEx()
文档:
The process identifier returned in the
SERVICE_STATUS_PROCESS
structure is valid provided that the state of the service is one ofSERVICE_RUNNING
,SERVICE_PAUSE_PENDING
,SERVICE_PAUSED
, orSERVICE_CONTINUE_PENDING
. If the service is in aSERVICE_START_PENDING
orSERVICE_STOP_PENDING
state, however, the process identifier may not be valid, and if the service is in theSERVICE_STOPPED
state, it is never valid.
仅仅因为您可以获得服务的 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;
}