Necesito obtener una lista de todos los procesos en un sistema de Windows incluyendo 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 ejecuta otro usuario).obtener el nombre del proceso desde el proceso id (win32)
Respuesta
CreateToolhelp32Snapshot() le dará el nombre del proceso (pero no la ruta); aparte de eso, tendrá que llamar a OpenProcess(). Si su código se está ejecutando en un contexto administrativo, puede habilitar el privilegio SE_DEBUG_NAME para obtener acceso a los procesos que se ejecutan en otros contextos.
Tiene una opción diferente que puede usar para recibir nombres de ejecución de procesos (nombres de procesos como los que escribió). La mejor manera depende un poco del lenguaje de programación que utiliza y de otros requisitos. Por ejemplo, puede usar WMI. Otra forma más antigua es el uso de Performance Counters (consulte también An Introduction To Performance Counters). Para obtener los valores de los contadores sólo puede utilizar las operaciones de consulta de registro de la clave HKEY_PERFORMANCE_DATA
base (ver Retrieving Counter Data)
Una forma más que también puede ser bien utilizado 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 "indocumentados" pero desde hace muchos años campos muy conocidos. Si busca en Internet la definición de la estructura, multará a la documentación completa. Me pregunto si el estado del sombrero de la función no está completo documentado. La función fue al menos en NT 3.5 (probablemente también antes) y ahora se puede usar bien en Windows 7 de 32 o 64 bits. Para ser exactos a continuación encontrará un pequeño programa de prueba C, que imprime todos los identificadores de proceso con los nombres exe correspondiente (no la ruta completa exe, sólo el nombre de 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;
}
¡Fantástico! Me ahorro mucho tiempo. Solo una nota al margen: hay una pérdida de memoria en la que no estás liberando "pspid". Aún así es impresionante :-) – Dan
Es muy fácil "arreglar" la pérdida de memoria. Realmente solo es necesario que uses el código como parte de la función. Para hacer esto, basta con guardar el valor de 'pspid' después del primer ciclo en otra variable (porque en el código actual se modificará el valor) y llamar' free' con el puntero. – Oleg
que pueda obtener el identificador de proceso y name
de todos los procesos en ejecución usando la API ToolHelp.
El siguiente código mostrará pid
y name
para 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);
}
}
solo necesita usar: pe32.dwSize = sizeof (PROCESSENTRY32); antes de llamar a Process32First() – hB0
@ hB0 - Perdí ese = = – Cyclonecode
Esto es realmente genial y mucho más rápido que la técnica 'NtQuerySystemInformation'. Sin embargo, ¿hay alguna manera de obtener el tiempo de creación de PID con esta técnica? – Noitidart
- 1. ¿Cómo obtener el ID del proceso del nombre del proceso?
- 2. Win32API - ¿Cómo obtener el nombre de archivo del proceso desde el control del proceso?
- 3. ¿Cómo obtener el ID de proceso actual?
- 4. Detectando el nombre de usuario del proceso ID
- 5. Obtener nombre del proceso por PID
- 6. cómo obtener el identificador del proceso desde la identificación del proceso?
- 7. Win32: ¿Cómo obtener el proceso/thread que posee un mutex?
- 8. ¿Cómo obtener el PID de un proceso dando el nombre del proceso en Mac OS X?
- 9. Obtener el nombre del proceso de pid o manejar
- 10. ¿Cómo obtener el nombre actual del proceso en Linux?
- 11. Cómo obtener el nombre del proceso en C++
- 12. ¿Cómo obtener el nombre del proceso de una aplicación?
- 13. Cambiar el nombre del proceso en Linux
- 14. ¿Cambiar el nombre del proceso en C#?
- 15. Busque un ID de proceso por nombre
- 16. Redireccionando la salida del comando ps, obteniendo el ID del proceso y matando ese proceso usando el script de shell
- 17. Mata el proceso por nombre de archivo
- 18. C++ Obtener nombre de usuario Proceso De
- 19. Cómo escribir datos en el proceso STDIN del proceso externo?
- 20. ¿Obtiene el nombre del proceso actual (ejecutable) en Go?
- 21. obtener pid del proceso hijo
- 22. Cómo llamar a una DLL .NET desde un proceso Win32?
- 23. Buscar todos los hilos de un proceso dado proceso id
- 24. ¿Cómo obtener el nombre de un hilo Win32?
- 25. Proceso de ejecución dado el proceso handle
- 26. Manejando el hilo principal del proceso
- 27. Cómo obtener el nombre del recurso desde el ID del recurso
- 28. ¿Cómo cambiar el nombre del proceso java.exe/javaw.exe?
- 29. ¿Aumenta el privilegio del proceso programáticamente?
- 30. Obtener hwnd por identificación del proceso C++
No creo que pueda hacer esto de manera confiable en las versiones de Windows después de Vista. ¿Qué versión está utilizando? –
podría usar WMI para este –
¿Qué quiere decir con el nombre del proceso, el nombre EXE? –