Ответ 1
Наконец-то я нашел решение (цифры после публикации здесь в качестве моей последней отчаянной попытки). Если кому-то нужен только список имен процессов, запущенных в системе (все процессы), это сделает это за вас.
В настоящее время я использую функцию EnumProcesses для получения списка запущенных процессов. Однако, поскольку мое приложение работает в пространстве пользователя, оно не способно обрабатывать процессы, которые не выполняются под пользователем, включая системные процессы. Есть ли другой способ, который даст мне доступ к ним? Все, что мне нужно, это имена процессов.
Наконец-то я нашел решение (цифры после публикации здесь в качестве моей последней отчаянной попытки). Если кому-то нужен только список имен процессов, запущенных в системе (все процессы), это сделает это за вас.
Чтобы добавить к этому ответу, я построил это для случаев, когда вы ищете только один конкретный процесс, а не весь список.
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 (С++ Builder) и в системе @Remy_Lebeau System:: AnsiString - это строковый класс С++ Builder для 8-битных символов ANSI в своих инфраструктурах VCL/FMX.
Если вам нужны только имена процессов, используйте 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 (Script)). Класс Win32_Process
содержит то, что вам нужно.
Однако я не тестировал это, я думаю, вы найдете ту же проблему: не-администратор может видеть только свои процессы.