Cómo hacer que las ventanas del programa win32 abiertas a través de procesos sean siempre ventanas de nivel superiorEnumeración de ventanas de nivel superior Puede ser más fácil enumerar ventanas de nivel superior en el escritorio que enumerar procesos. La forma de enumerar las ventanas de nivel superior del escritorio es utilizar la función EnumWindows(). No utilice GetWindow() para crear una lista de ventanas porque las relaciones complejas entre padres, hijos y hermanos (orden Z) entre ventanas pueden causar confusión y hacer que los resultados de la enumeración sean inexactos. La función de devolución de llamada se llama una vez para cada ventana del escritorio (o ventana de nivel superior). Luego, la función de devolución de llamada realiza algún procesamiento del identificador de la ventana, como agregarlo a una lista. Este enfoque garantiza que los resultados de la enumeración no estén saturados por jerarquías de ventanas complejas, por lo que una vez que tengamos el identificador de la ventana podemos usar GetWindowText() para obtener el título de la ventana. Enumerar procesos para crear una lista de procesos del sistema es un poco más complicado que enumerar ventanas. Esto se debe principalmente a que las funciones API utilizadas dependen de diferentes sistemas operativos Win32. En Windows 9x, Windows Me, Windows 2000 Professional y Windows XP podemos utilizar la API de la biblioteca ToolHelp32. Pero en Windows NT tenemos que utilizar la API de la biblioteca PSAPI que forma parte del SDK. Este artículo discutirá cómo implementar esto en todas las plataformas anteriores. El programa de muestra adjunto encapsula la API en la biblioteca anterior, por lo que las funciones encapsuladas son compatibles con todos los sistemas operativos Win32. Utilice la biblioteca ToolHelp32 para enumerar procesos. Las funciones de la biblioteca ToolHelp32 se encuentran en KERNEL32.dll y son funciones API estándar. La biblioteca ToolHelp32 contiene funciones que se pueden utilizar para enumerar procesos y subprocesos en el sistema y obtener información de memoria y módulos. Para enumerar procesos, simplemente use estas tres funciones: CreateToolhelp32Snapshot(), Process32First() y Process32Next(). El primer paso para utilizar la función ToolHelp32 es crear una "instantánea" de la información del sistema utilizando la función CreateToolhelp32Snapshot(). Esta función le permite seleccionar el tipo de información que se almacenará en la instantánea. Si solo está interesado en la información del proceso, simplemente incluya el indicador TH32CS_SNAPPROCESS. La función CreateToolhelp32Snapshot() devuelve un HANDLE, que debe pasarse a CloseHandle() una vez completada la llamada. El siguiente paso es llamar a la función Process32First una vez para obtener la lista de procesos de la instantánea y luego llamar a la función Process32Next repetidamente hasta que la función devuelva FALSO. Esto iterará sobre la lista de procesos en la instantánea. Ambas funciones requieren dos parámetros, el identificador de instantánea y una estructura PROCESSENTRY32. Después de llamar a Process32First o Process32Next, PROCESSENTRY32 contendrá información clave sobre los procesos en el sistema. El ID del proceso se almacena en esta estructura como th32ProcessID, que se puede pasar a la API OpenProcess() para obtener un identificador del proceso. El nombre del archivo ejecutable correspondiente y su ruta se almacenan en la estructura szExeFile. Esta estructura también contiene otra información útil. Nota: Antes de llamar a Process32First(), asegúrese de configurar el miembro dwSize de la estructura PROCESSENTRY32 en sizeof(PROCESSENTRY32). Enumeración de procesos mediante la biblioteca PSAPI En Windows NT, utilice las funciones PSAPI en PSAPI.DLL para crear una lista de procesos.
Este archivo se distribuye con Platform SDK y la última versión se puede descargar aquí: Los archivos PSAPI.h y PSAPI.lib necesarios para usar la biblioteca también se encuentran en Platform SDK. Para utilizar la funcionalidad de la biblioteca PSAPI, debe agregar PSAPI.lib a su proyecto de código e incluir el archivo PSAPI.h en todos los módulos que llaman a la API de PSAPI. Recuerde distribuir PSAPI.DLL con el archivo ejecutable porque no se distribuye con Windows NT. Puede descargar la versión distribuible de PSAPI.DLL por separado (sin descargar el SDK de plataforma completo) aquí. Al igual que ToolHelp32, la biblioteca PSAPI contiene una variedad de funciones útiles. Debido al espacio limitado, este artículo solo analizará las funciones relacionadas con los procesos de enumeración: EnumProcesses(), EnumProcessModules(), GetModuleFileNameEx() y GetModuleBaseName(). El primer paso para crear una lista de procesos es llamar a EnumProcesses(). La declaración de la función es la siguiente BOOL EnumProcesses(DWORD *lpidProcess, DWORD cb, DWORD *cbNeeded() acepta tres parámetros, a saber, un puntero a la matriz de tipo DWORD lpidProcess, el tamaño de la matriz cb y el puntero DWORD cbNeeded que recibe la longitud de los datos devueltos. cbNeeded devuelve el tamaño de la memoria utilizada por la matriz. La siguiente fórmula muestra la cantidad de procesos devueltos: nReturned = cbNeeded / sizeof(DWORD). NOTA: Aunque la documentación denomina el DWORD devuelto "cbNeeded", no sabemos exactamente qué tamaño de matriz pasar. EnumProcesses() no devuelve un valor de matriz en cbNeeded que sea mayor que el valor pasado en el parámetro cb. Por lo tanto, la única forma de garantizar que la función EnumProcesses() tenga éxito es asignar una matriz de DWORD, y si el cbNeeded devuelto es igual a cb, entonces asigne una matriz más grande y siga intentándolo hasta que cbNeeded sea menor que cb. tener una matriz, sus elementos contienen el ID de cada proceso en el sistema. Para obtener un identificador del ID del proceso, llame a OpenProcess(). Después de obtener el identificador, debe obtener el primer módulo del proceso. Para hacer esto, necesita llamar a la API EnumProcessModules(): EnumProcessModules(hProcess, hModule, sizeof(hModule), cbReturned); después de la llamada, lo que se almacena en la variable hModule será el primer módulo del proceso. Recuerde, un proceso en realidad no tiene nombre, pero el primer módulo de un proceso es el módulo ejecutable del proceso. Ahora puede obtener la ruta completa o el nombre del proceso ejecutable llamando a las funciones API GetModuleFileNameEx() o GetModuleBaseName() utilizando el identificador del módulo devuelto en hModule. Ambas funciones requieren cuatro parámetros: un identificador de proceso, un identificador de módulo, un puntero de búfer que devuelve un nombre y el tamaño del búfer. Al repetir esta llamada para cada ID de proceso devuelto por la API EnumProcesses() se crea una lista de procesos para Windows NT.