Win32 – Récupère le nom de l’application principale

J’ai injecté mon dll dans le processus. Comment puis-je obtenir le handle de la fenêtre principale de l’application hôte?

L’application hôte peut avoir plusieurs «fenêtres principales». Pour les détecter, vous pourriez

  1. Appelez GetCurrentProcessId pour obtenir le PID du processus en cours
  2. Appelez EnumWindows pour parcourir toutes les fenêtres de niveau supérieur du bureau
  3. Pour chaque fenêtre du bureau, appelez GetWindowThreadProcessId pour obtenir le PID du processus qui a créé la fenêtre.
  4. Si le PID de la fenêtre correspond au PID de votre propre processus, mémorisez la fenêtre.

Cela vous donne une liste des fenêtres de niveau supérieur créées par le processus dans lequel vous avez injecté votre DLL. Toutefois, veuillez noter que cette approche peut générer des fenêtres détruites au moment où vous traitez la liste de fenêtres créée. Par conséquent, lorsque vous faites quelque chose avec Windows, veillez à utiliser la fonction IsWindow pour vous assurer que la fenêtre disponible est toujours valide (ceci est toujours sujet aux conditions de IsWindow car la fenêtre peut devenir invalide entre votre appel à IsWindow et l’access à la fenêtre). , mais la fenêtre de temps est beaucoup plus petite).

Voici une fonction C ++ implémentant cet algorithme. Il implémente une fonction getToplevelWindows qui produit un std::vector contenant les descripteurs de toutes les fenêtres de niveau supérieur du processus en cours.

 struct EnumWindowsCallbackArgs { EnumWindowsCallbackArgs( DWORD p ) : pid( p ) { } const DWORD pid; std::vector handles; }; static BOOL CALLBACK EnumWindowsCallback( HWND hnd, LPARAM lParam ) { EnumWindowsCallbackArgs *args = (EnumWindowsCallbackArgs *)lParam; DWORD windowPID; (void)::GetWindowThreadProcessId( hnd, &windowPID ); if ( windowPID == args->pid ) { args->handles.push_back( hnd ); } return TRUE; } std::vector getToplevelWindows() { EnumWindowsCallbackArgs args( ::GetCurrentProcessId() ); if ( ::EnumWindows( &EnumWindowsCallback, (LPARAM) &args ) == FALSE ) { // XXX Log error here return std::vector(); } return args.handles; } 

MISE À JOUR: Ces jours-ci (environ quatre ans après avoir donné la réponse), je considérerais également parcourir la liste des threads de l’application, puis utiliser EnumThreadWindows sur chaque thread. J’ai remarqué que cela est beaucoup plus rapide dans de nombreux cas.