【发布时间】:2018-06-25 04:47:32
【问题描述】:
我正在尝试使用 C++ 获取系统中运行的进程列表。我使用 Windows API 中可用的函数(如 OpenProcess 和 CreateToolhelp32Snapshot )来完成它。
问题是代码对于大多数进程都可以正常工作,但无法单独获取关键系统进程的内存信息,我也提供了 seDebugPrivilege 并且仅以管理员身份运行程序。
我得到像
这样的输出File Name PID Memory Used
winlogon.exe 1248 2432 KB
fontdrvhost.exe 1308
WARNING: GetProcessMemoryInfo failed with error 6 (The handle is invalid)
dwm.exe 1384
WARNING: GetProcessMemoryInfo failed with error 6 (The handle is invalid)
svchost.exe 1448 4744 KB
我的代码是:
BOOL GetProcessList( )
{
HANDLE hProcessSnap;
HANDLE hProcess;
HANDLE hToken;
PROCESSENTRY32 pe32;
DWORD dwPriorityClass;
PROCESS_MEMORY_COUNTERS pmc;
hProcessSnap = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
if( hProcessSnap == INVALID_HANDLE_VALUE )
{
char err[]="CreateToolhelp32Snapshot (of processes)";
printError( err );
return( FALSE );
}
pe32.dwSize = sizeof( PROCESSENTRY32 );
if( !Process32First( hProcessSnap, &pe32 ) )
{
char err[]="Process32First";
printError( err ); // show cause of failure
CloseHandle( hProcessSnap ); // clean the snapshot object
return( FALSE );
}
if(!OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, FALSE, &hToken))
{
if (GetLastError() == ERROR_NO_TOKEN)
{
if (!ImpersonateSelf(SecurityImpersonation))
return FALSE;
if(!OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, FALSE, &hToken)){
char err[]="OpenThreadToken";
printError( err );
return FALSE;
}
}
else
return FALSE;
}
SetPrivilege(hToken, SE_DEBUG_NAME, FALSE);
do
{
printf( "%-25s", pe32.szExeFile );
dwPriorityClass = 0;
SIZE_T dwMin, dwMax;
hProcess = OpenProcess( PROCESS_QUERY_LIMITED_INFORMATION , FALSE, pe32.th32ProcessID );
printf("%-10d", pe32.th32ProcessID );
if(GetProcessMemoryInfo( hProcess, (PROCESS_MEMORY_COUNTERS *)&pmc, sizeof(pmc)))
{
printf( "%-10d KB", pmc.PagefileUsage/1024);
} else{
char err[]="GetProcessMemoryInfo";
printError( err );
}
printf("\n");
CloseHandle(hProcess);
}while( Process32Next( hProcessSnap, &pe32 ) );
CloseHandle( hProcessSnap );
return( TRUE );
}
【问题讨论】:
-
也许这个例子可能有用:pastebin.com/KjBzMEY0。我认为你有这个问题 - stackoverflow.com/questions/28303436/…。也使用 PROCESS_QUERY_LIMITED_INFORMATION
-
你没有检查
OpenProcess的结果。在某些进程中它失败并因此在调用GetProcessMemoryInfo中使用无效句柄返回给您错误 - 无效句柄。必须是 -
您也没有关闭
hToken并且看起来无法分配调试权限,只有这样才能解释为什么您无法打开某些进程。还可以在枚举进程之前调整权限 -
@HelpingHand 我正在使用
PROCESS_QUERY_LIMITED_INFORMATION,是的,在发布这个问题之前我确实看过那篇文章 -
我同意 RbMm。
SetPrivilege似乎有问题。如果线程令牌启用了调试权限,那么打开一个进程以仅查询有限的信息应该不会失败,即使对于受保护的进程也是如此。
标签: c++ windows winapi process