【发布时间】:2011-03-29 11:20:03
【问题描述】:
我目前正在使用 EnumProcesses 函数来获取正在运行的进程列表。但是,由于我的应用程序在用户空间中运行,因此它无法获取不在用户下运行的进程的句柄,包括系统进程。是否有另一种方法可以让我访问这些?我只需要进程名称。
【问题讨论】:
标签: winapi visual-c++ process
我目前正在使用 EnumProcesses 函数来获取正在运行的进程列表。但是,由于我的应用程序在用户空间中运行,因此它无法获取不在用户下运行的进程的句柄,包括系统进程。是否有另一种方法可以让我访问这些?我只需要进程名称。
【问题讨论】:
标签: winapi visual-c++ process
我终于找到了解决方案(作为我最后一次绝望尝试后的数字)。如果其他人只需要系统上运行的进程名称列表(所有进程),这将为您完成。
【讨论】:
只是为了补充这个答案,我为您只寻找一个特定进程而不是整个列表的情况构建了这个。
bool FindRunningProcess(AnsiString process) {
/*
Function takes in a string value for the process it is looking for like ST3Monitor.exe
then loops through all of the processes that are currently running on windows.
If the process is found it is running, therefore the function returns true.
*/
AnsiString compare;
bool procRunning = false;
HANDLE hProcessSnap;
PROCESSENTRY32 pe32;
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hProcessSnap == INVALID_HANDLE_VALUE) {
procRunning = false;
} else {
pe32.dwSize = sizeof(PROCESSENTRY32);
if (Process32First(hProcessSnap, &pe32)) { // Gets first running process
if (pe32.szExeFile == process) {
procRunning = true;
} else {
// loop through all running processes looking for process
while (Process32Next(hProcessSnap, &pe32)) {
// Set to an AnsiString instead of Char[] to make compare easier
compare = pe32.szExeFile;
if (compare == process) {
// if found process is running, set to true and break from loop
procRunning = true;
break;
}
}
}
// clean the snapshot object
CloseHandle(hProcessSnap);
}
}
return procRunning;
}
我应该在这里注意到这是在 Embarcadero RAD Studio (C++ Builder) 中编写的,并且每个 @Remy_Lebeau System::AnsiString 是一个 C++Builder 字符串类,用于其 VCL/FMX 框架中的 8 位 ANSI 字符数据。
【讨论】:
如果您只需要进程名称,请使用WTSEnumerateProcesses:
WTS_PROCESS_INFO* pWPIs = NULL;
DWORD dwProcCount = 0;
if(WTSEnumerateProcesses(WTS_CURRENT_SERVER_HANDLE, NULL, 1, &pWPIs, &dwProcCount))
{
//Go through all processes retrieved
for(DWORD i = 0; i < dwProcCount; i++)
{
//pWPIs[i].pProcessName = process file name only, no path!
//pWPIs[i].ProcessId = process ID
//pWPIs[i].SessionId = session ID, if you need to limit it to the logged in user processes
//pWPIs[i].pUserSid = user SID that started the process
}
}
//Free memory
if(pWPIs)
{
WTSFreeMemory(pWPIs);
pWPIs = NULL;
}
使用此方法的好处是,您不必单独打开每个进程,然后检索其名称,如果您使用 EnumProcesses 则必须这样做,如果您尝试打开以比您的用户帐户更高的权限运行的进程。
此外,这种方法也比在循环中调用Process32First()/Process32Next() 快得多。
WTSEnumerateProcesses 是一个鲜为人知的 API,自 Windows XP 以来就已经可用。
【讨论】:
WMI 查询(很可能使用 WMI 的 COM 接口,但您需要翻译以 VB(脚本)为重点的文档)在这里可能会有所帮助。 Win32_Process 类包含您需要的内容。
但是,我没有对此进行测试,我想你会发现同样的问题:非管理员只能看到自己的进程。
【讨论】: