winapi process pid

winapi - obtener el nombre del proceso desde el id de proceso(win32)



process pid (3)

Necesito obtener una lista de todos los procesos en un sistema de Windows, incluidos los nombres y PID.
EnumProcess puede obtener una lista de pids, pero ¿cómo obtengo el nombre del proceso del pid? No quiero llamar a OpenProcess en el proceso, ya que no siempre funciona (como si el otro proceso lo ejecute otro usuario).


CreateToolhelp32Snapshot () le dará el nombre del proceso (pero no la ruta); Aparte de eso, deberás llamar a OpenProcess (). Si su código se ejecuta en un contexto administrativo, puede habilitar el privilegio SE_DEBUG_NAME para obtener acceso a los procesos que se ejecutan en otros contextos.


Tiene diferentes opciones que puede usar para recibir los nombres de ejecución de los procesos actualmente en ejecución (nombres de proceso como los que escribió). La mejor manera depende un poco del lenguaje de programación que utilice y de otros requisitos. Por ejemplo, puede utilizar WMI. Otra forma más antigua es el uso de contadores de rendimiento (consulte también Introducción a los contadores de rendimiento ). Para obtener los valores de los contadores, solo puede usar las operaciones de consulta del registro desde la clave base HKEY_PERFORMANCE_DATA (consulte Recuperación de datos del contador )

Otra forma que también puede ser utilizada es la función NtQuerySystemInformation con SystemProcessInformation como parámetro. EnumProcess y muchas otras API de Windows usan la función internamente. La estructura SYSTEM_PROCESS_INFORMATION definida en la documentación de NtQuerySystemInformation tiene muchos NtQuerySystemInformation "no documentados" pero desde hace muchos años, bien conocidos. Si busca en Internet la definición de la estructura, se le multará toda la documentación. Me pregunto si el estado de la función no está completamente documentado. La función estaba al menos en NT 3.5 (probablemente también antes) y puede usarse bien ahora en Windows 7 de 32 o 64 bits. Para ser exactos a continuación, encontrará un pequeño programa de prueba de C que imprime todos los identificadores de proceso con los nombres de archivo ejecutables correspondientes (no la ruta de archivo ejecutable completa, solo el nombre del archivo):

#include <Windows.h> // one can also use Winternl.h if needed //#include <Winternl.h> // for UNICODE_STRING and SYSTEM_INFORMATION_CLASS #include <stdio.h> #include <tchar.h> #define STATUS_SUCCESS ((NTSTATUS)0x00000000L) #define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L) typedef enum _SYSTEM_INFORMATION_CLASS { SystemProcessInformation = 5 } SYSTEM_INFORMATION_CLASS; typedef struct _UNICODE_STRING { USHORT Length; USHORT MaximumLength; PWSTR Buffer; } UNICODE_STRING; typedef LONG KPRIORITY; // Thread priority typedef struct _SYSTEM_PROCESS_INFORMATION_DETAILD { ULONG NextEntryOffset; ULONG NumberOfThreads; LARGE_INTEGER SpareLi1; LARGE_INTEGER SpareLi2; LARGE_INTEGER SpareLi3; LARGE_INTEGER CreateTime; LARGE_INTEGER UserTime; LARGE_INTEGER KernelTime; UNICODE_STRING ImageName; KPRIORITY BasePriority; HANDLE UniqueProcessId; ULONG InheritedFromUniqueProcessId; ULONG HandleCount; BYTE Reserved4[4]; PVOID Reserved5[11]; SIZE_T PeakPagefileUsage; SIZE_T PrivatePageCount; LARGE_INTEGER Reserved6[6]; } SYSTEM_PROCESS_INFORMATION_DETAILD, *PSYSTEM_PROCESS_INFORMATION_DETAILD; typedef NTSTATUS (WINAPI *PFN_NT_QUERY_SYSTEM_INFORMATION)( IN SYSTEM_INFORMATION_CLASS SystemInformationClass, IN OUT PVOID SystemInformation, IN ULONG SystemInformationLength, OUT OPTIONAL PULONG ReturnLength ); int main() { size_t bufferSize = 102400; PSYSTEM_PROCESS_INFORMATION_DETAILD pspid= (PSYSTEM_PROCESS_INFORMATION_DETAILD) malloc (bufferSize); ULONG ReturnLength; PFN_NT_QUERY_SYSTEM_INFORMATION pfnNtQuerySystemInformation = (PFN_NT_QUERY_SYSTEM_INFORMATION) GetProcAddress (GetModuleHandle(TEXT("ntdll.dll")), "NtQuerySystemInformation"); NTSTATUS status; while (TRUE) { status = pfnNtQuerySystemInformation (SystemProcessInformation, (PVOID)pspid, bufferSize, &ReturnLength); if (status == STATUS_SUCCESS) break; else if (status != STATUS_INFO_LENGTH_MISMATCH) { // 0xC0000004L _tprintf (TEXT("ERROR 0x%X/n"), status); return 1; // error } bufferSize *= 2; pspid = (PSYSTEM_PROCESS_INFORMATION_DETAILD) realloc ((PVOID)pspid, bufferSize); } for (;; pspid=(PSYSTEM_PROCESS_INFORMATION_DETAILD)(pspid->NextEntryOffset + (PBYTE)pspid)) { _tprintf (TEXT("ProcessId: %d, ImageFileName: %ls/n"), pspid->UniqueProcessId, (pspid->ImageName.Length && pspid->ImageName.Buffer)? pspid->ImageName.Buffer: L""); if (pspid->NextEntryOffset == 0) break; } return 0; }


Puede obtener el name y el identificador del proceso para todos los procesos en ejecución utilizando la API ToolHelp .
El siguiente código mostrará el pid y el name de cada proceso.

void showProcessInformation() { HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if(hSnapshot) { PROCESSENTRY32 pe32; pe32.dwSize = sizeof(PROCESSENTRY32); if(Process32First(hSnapshot, &pe32)) { do { printf("pid %d %s/n", pe32.th32ProcessID, pe32.szExeFile); } while(Process32Next(hSnapshot, &pe32)); } CloseHandle(hSnapshot); } }