Nom du processus pour la fenêtre active dans Windows 8/10
l'échantillon suivant a retourné de manière fiable le nom du processus associé à la fenêtre active, mais ne fonctionne pas avec les nouvelles applications modernes / universelles parce qu'il renvoie le nom d'un processus helper WWAHost.exe sur Windows 8 et Application Framehost.exe sur Windows 10, plutôt que le nom de l'application.
HWND active_window = GetForegroundWindow();
GetWindowThreadProcessId(active_window, &active_process_id);
HANDLE active_process = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, active_process_id);
GetProcessImageFileName(active_process, image_name, 512);
avec Windows 10 L'ApplicationFrameHost.exe est le processus qui crée les poignées de fenêtre et est ce que retourné par GetWindowThreadProcessId(), y a-t-il une autre API Win32 qui peut être utilisée pour obtenir le processus actif de l'application universelle qui est active?
a également essayé D'utiliser GetApplicationUserModelId() et GetPackageFullName () avec aucun succès car ils retournent respectivement APPMODEL_ERROR_NO_APPLICATION et APPMODEL_ERROR_NO_PACKAGE parce que la poignée active_process est juste le processus d'AIDE et non le processus de l'application active.
tout autre API à utiliser pour obtenir le nom du processus Moderne/Universal application donnée, le hwnd de la fenêtre, ou autrement, figure le nom de processus de l'application universelle est active.
Merci d'avance!
4 réponses
assurez-vous d'utiliser L'utilitaire Spy++ lorsque vous voulez rétro-concevoir quelque chose comme ça. Inclus avec Visual Studio, vous avez besoin de la version 64 bits dans Common7\Tools\spyxx_amd64.EXE. Utilisez la recherche > trouvez la fenêtre et faites glisser le bullseye vers une application UWP, comme la météo.
Vous verrez la fenêtre que vous trouverez avec GetForegroundWindow (), elle a au moins 3 enfants windows:
- ApplicationFrameTitleBarWindow
- ApplicationFrameInputSinkWindow
- Windows.Core.INTERFACE.CoreWindow, c'est la fenêtre hôte de L'application UWP et celle qui vous intéresse. Droit-cliquez dessus et sélectionnez Propriétés, onglet Processus, cliquez sur L'ID du processus. Cela vous amène au processus de propriétaire réel que vous voulez savoir.
Si vous avez juste besoin de faire une étape supplémentaire à partir du code que vous avez déjà, vous avez juste à énumérer l'enfant windows et recherchez une avec un propriétaire différent du processus. Certains codes C, essayant de les rendre aussi universels que possible sans faire trop de suppositions et pas assez de vérification des erreurs:
#include <stdio.h>
#include <Windows.h>
typedef struct {
DWORD ownerpid;
DWORD childpid;
} windowinfo;
BOOL CALLBACK EnumChildWindowsCallback(HWND hWnd, LPARAM lp) {
windowinfo* info = (windowinfo*)lp;
DWORD pid = 0;
GetWindowThreadProcessId(hWnd, &pid);
if (pid != info->ownerpid) info->childpid = pid;
return TRUE;
}
int main()
{
Sleep(2000);
HWND active_window = GetForegroundWindow();
windowinfo info = { 0 };
GetWindowThreadProcessId(active_window, &info.ownerpid);
info.childpid = info.ownerpid;
EnumChildWindows(active_window, EnumChildWindowsCallback, (LPARAM)&info);
HANDLE active_process = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, info.childpid);
WCHAR image_name[MAX_PATH] = { 0 };
DWORD bufsize = MAX_PATH;
QueryFullProcessImageName(active_process, 0, image_name, &bufsize);
wprintf(L"%s\n", image_name);
CloseHandle(active_process);
return 0;
}
sortie sur le programme Météo:
C:\Program Fichiers\WindowsApps\Microsoft.BingWeather_4.5.168.0_x86_ _ 8wekyb3d8bbwe\ Microsoft.Msn.Météo.exe
Voici une petite application d'application d'application de console qui en continu (de sorte que vous pouvez le tester en sélectionnant facilement différentes fenêtres sur votre bureau) affiche des informations sur le processus de fenêtre de premier plan courant et stocker le processus, le cas échéant.
Les applications peuvent avoir une hiérarchie de fenêtres qui peut couvrir plusieurs processus. Ce que je fais ici est de rechercher la première sous-fenêtre qui a le 'Windows.INTERFACE.Core.Nom de classe de CoreWindow.
Cette application utilise le API UIAutomation (et aussi intelligent pointeurs, smart BSTRs et Smart variantes fournies par la directive #import). Je suppose que vous pouvez faire la même chose avec Windows SDK standard, mais je trouve L'UIAutomation utilisé de cette façon très élégant.
#include "stdafx.h"
#import "UIAutomationCore.dll"
using namespace UIAutomationClient;
int main()
{
// initialize COM, needed for UIA
CoInitialize(NULL);
// initialize main UIA class
IUIAutomationPtr pUIA(__uuidof(CUIAutomation));
do
{
// get the Automation element for the foreground window
IUIAutomationElementPtr foregroundWindow = pUIA->ElementFromHandle(GetForegroundWindow());
wprintf(L"pid:%i\n", foregroundWindow->CurrentProcessId);
// prepare a [class name = 'Windows.UI.Core.CoreWindow'] condition
_variant_t prop = L"Windows.UI.Core.CoreWindow";
IUIAutomationConditionPtr condition = pUIA->CreatePropertyCondition(UIA_ClassNamePropertyId, prop);
// get the first element (window hopefully) that satisfies this condition
IUIAutomationElementPtr coreWindow = foregroundWindow->FindFirst(TreeScope::TreeScope_Children, condition);
if (coreWindow)
{
// get the process id property for that window
wprintf(L"store pid:%i\n", coreWindow->CurrentProcessId);
}
Sleep(1000);
} while (TRUE);
cleanup:
CoUninitialize();
return 0;
}
est-ce que prendre un instantané des processus en cours d'exécution et en extraire le nom en comparant l'id du processus ne fonctionne pas? Référence complète ici:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms686837(v=vs. 85).aspx
mais vous fixez le snapshot avec CreateToolhelp32Snapshot ().
Ou de WTSEnumerateProcesses() et ses environs API?
Je suis sûr que ça a marché dans Win 8. Elle est cassée en 10?
à partir de Win10 mise à jour anniversaire ApplicationFrameHost fenêtre enfant retourner tout sauf UWP application. Il n'a fonctionné qu'en mode tablette après relogon.