2010-08-13 11 views
14

Obecnie używam funkcji EnumProcesses, aby uzyskać listę uruchomionych procesów. Ponieważ moja aplikacja działa w przestrzeni użytkownika, nie jest jednak w stanie uzyskać uchwytów dla procesów nie działających pod użytkownikiem, w tym procesów systemowych. Czy istnieje inna metoda, która da mi dostęp do nich? Potrzebuję tylko nazw procesów.Uzyskaj pełną listę procesów (Visual C++)

Odpowiedz

9

W końcu znalazłem rozwiązanie (dane po zamieszczeniu tutaj jako moją ostatnią desperacką próbę). Jeśli ktokolwiek jeszcze potrzebuje listy nazw procesów uruchomionych w systemie (wszystkie procesy), zrobi to za Ciebie.

Process Walking

0

Zapytanie WMI (całkiem możliwe przy użyciu interfejsu COM WMI, ale trzeba przetłumaczyć dokumentację skoncentrowaną na VB (Script)) może pomóc tutaj. Klasa Win32_Process zawiera to, czego potrzebujesz.

Jednak nie testowałem tego, myślę, że znajdziesz ten sam problem: nie-administrator może zobaczyć tylko własne procesy.

8

Wystarczy dodać do tej odpowiedzi, Zbudowałem to dla przypadków, gdy szukasz dla jednego konkretnego procesu zamiast całej listy.

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; 
} 

Należy zauważyć tutaj ten został napisany w Embarcadero RAD Studio (C++ Builder) i za @Remy_Lebeau System :: AnsiString jest klasa ciąg C++ Builder dla danych znakowych 8bit ANSI w jego ramach VCL/FMX.

+0

Może Cię to zainteresować: http://stackoverflow.com/q/30604485/560648. –

+0

Dziękuję, powinienem zauważyć, że to zostało napisane w Embarcadero RAD Studio (C++ Builder) i na @Remy_Lebeau System :: AnsiString jest klasą napisową C++ Builder dla 8-bitowych danych ANSI w swoich frameworkach VCL/FMX. – Phil

+0

Zdecydowanie warto dodać ten szczegół do odpowiedzi! Twoje zdrowie. –

1

Jeśli wszystko czego potrzebujesz to tylko nazwy procesu, a następnie użyć WTSEnumerateProcesses jako takie:

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; 
} 

Zaletą tej metody jest to, że nie trzeba otwierać każdy proces indywidualnie, a następnie odzyskać swoją nazwę jako co musielibyśmy zrobić, gdybyśmy poszli z EnumProcesses, co również nie zadziała, jeśli spróbujecie otworzyć procesy, które działają z wyższymi uprawnieniami niż konto użytkownika.

Ta metoda jest również znacznie szybsza niż wywoływanie w pętli Process32First()/Process32Next().

WTSEnumerateProcesses to mniej znany interfejs API, który jest dostępny od czasów systemu Windows XP.

Powiązane problemy