Получить полный список запущенных процессов (Visual С++)

В настоящее время я использую функцию EnumProcesses для получения списка запущенных процессов. Однако, поскольку мое приложение работает в пространстве пользователя, оно не способно обрабатывать процессы, которые не выполняются под пользователем, включая системные процессы. Есть ли другой способ, который даст мне доступ к ним? Все, что мне нужно, это имена процессов.

Ответы

Ответ 1

Наконец-то я нашел решение (цифры после публикации здесь в качестве моей последней отчаянной попытки). Если кому-то нужен только список имен процессов, запущенных в системе (все процессы), это сделает это за вас.

Хождение по процессу

Ответ 2

Чтобы добавить к этому ответу, я построил это для случаев, когда вы ищете только один конкретный процесс, а не весь список.

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.

Ответ 3

Если вам нужны только имена процессов, используйте 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.

Ответ 4

Запрос WMI (возможно, с использованием интерфейса WMI COM, но вам нужно будет перевести документацию, ориентированную на VB (Script)). Класс Win32_Process содержит то, что вам нужно.

Однако я не тестировал это, я думаю, вы найдете ту же проблему: не-администратор может видеть только свои процессы.