Cómo obtener la ventana principal de un proceso y el nombre del programa que creó el proceso
Primero, analicemos cómo obtener la ventana principal desde varias ventanas. En realidad, esto es muy simple. Esto se puede lograr utilizando dos funciones API. Estas dos API son EnumWindows y GetWindowThreadProcessId. Si no está familiarizado con estas dos funciones, no se preocupe, este artículo proporciona una clase C para encapsular estas dos API. Esta clase se llama CMainWindowIterator y se puede utilizar para enumerar todas las ventanas principales de un proceso (cuyo ID de proceso se conoce). Esto es exactamente lo que queremos. Funciona de la siguiente manera:
DWORD pid = // ID de proceso conocido
CMainWindowIterator itw(pid);
for (HWND hwnd = itw.First () ; hwnd; hwnd=itw.Next()) {
// Haz algo
}.
Es así de simple, CMainWindowIterator se deriva de una clase más general: CWindowIterator que es responsable de empaquetar: :EnumWindows funciones para ocultar los detalles de la devolución de llamada. Tiene una función virtual OnWindow que puede anular en su clase derivada para poder enumerar ventanas de la forma que desee. CMainWindowIterator puede sobrecargar la función OnWindow para obtener solo la ventana principal que pertenece a un proceso determinado: // (establezca m_pid en el constructor)
BOOL CMainWindowIterator::OnWindow(HWND hwnd)
{
if ((GetWindowLong(hwnd, GWL_STYLE) & WS_VISIBLE)){
DWORD pidwin;
GetWindowThreadProcessId(hwnd, & pidwin ); p>
if (pidwin==m_pid)
devuelve VERDADERO
}
devuelve FALSO
}
p>
Las dos clases se definen de la siguiente manera: (los archivos correspondientes son EnumProc.h y EnumProc.cpp)
Luego llame a GetModuleFileNameEx.
De hecho, como puede ver en la Figura 1 anterior, hemos implementado una lista de procesos y sus nombres de módulos correspondientes en el programa lp.exe.
Los detalles de implementación del programa también utilizan la función API de salida de PSAPI EnumProcesses para enumerar todos los procesos en ejecución. Para encapsular los detalles específicos, escribí dos clases C similares a CWindowIterator y CMainWindowIterator: CProcessIterator y CProcessModuleIterator, que encapsulan respectivamente las API EnumProcesses y EnumProcessModules. funciones. Con estas dos clases de encapsulación, todo se vuelve muy sencillo. CProcessIterator itp;
for (DWORD pid=itp.First(); pid; pid=itp.Next()) {
// Procesar cada proceso
}
El siguiente es el método para obtener el nombre del archivo EXE del proceso creado: CProcessModuleIterator itm(pid);
HMODULE hModule = itm.First(); EXE p>
TCHAR modname[_MAX_PATH];
GetModuleBaseName(itm.GetProcessHandle(), hModule, modname, _MAX_PATH);
Dado que lp no mostrará el archivo completo nombre del archivo del módulo de ruta, por lo que uso otra función PSAPI GetModuleBaseName en lugar de GetModuleFileNameEx para obtener el nombre de ruta completo. Además, dado que CProcessModuleIterator abre el módulo de enumeración de procesos, no es necesario llamar a OpenProcess y CProcessModuleIterator::GetProcessHandle se puede usar para obtener el identificador de un proceso abierto.
Las siguientes son las definiciones de CProcessIterator y CProcessModuleIterator: //////////////////////////////////////// ///// ////////////////////////////////////////////// ///
//Clase de enumeración de procesos: enumera todos los procesos en el sistema, pero siempre omite el primer proceso con PID = 0, es decir, el proceso inactivo (IDLE)
/
class CProcessIterator {
protected:
DWORD* m_ pids // Contiene antepasados de los ID de proceso
DWORD m_count; // Tamaño de la matriz
DWORD m_current; // Elemento de la matriz actual
public:
CProcessIterator()
~ CProcessIterator();
DWORD GetCount() { return m_count }
DWORD First()
DWORD Next() {
return m_pids amplificador; m_ actual lt; m_count ?m_pids[m_current]:
}
}
///////// ///// ////////////////////////////////////////////// //////// /
// Los módulos del proceso que se enumerarán. El primer módulo es el programa exe principal que crea este proceso
//p>
clase CProcessModuleIterator {
protected:
HANDLE m_hProcess; // Mango del proceso
HMODULE* m_ hModules; // Matriz de mango del módulo
DWORD m_count; // Tamaño de la matriz
DWORD m_current; Identificador del módulo
public.ProcessModuleIterator(CProcessModuleIterator)
CProcessModuleIterator(DWORD pid);
~CProcessModuleIterator();
HANDLE GetProcessHandle ( ) { return m_hProcess;}
DWORD GetCount() { return m_count }
HMODULE First();
HMODULE Next() {
devuelve m_hProcess amp; m_current lt; m_count ?m_hModules[m_current]: 0; ; m_actual lt; m_count?