次のサンプルは、アクティブウィンドウに関連付けられているプロセスの名前を確実に返しましたが、ヘルパープロセスの名前を返すため、新しいモダン/ユニバーサルアプリでは機能しませんWWAHost.exe on Windows 8およびApplicationFrameHost.exe Windows 10では、アプリの名前ではありません。
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);
Windows 10では、ApplicationFrameHost.exeはウィンドウハンドルを作成するプロセスであり、GetWindowThreadProcessId()によって返されるものですが、アクティブなユニバーサルアプリのアクティブなプロセスを取得するために使用できる別のWin32 APIはありますか?
また、GetApplicationUserModelId()とGetPackageFullName()を使用してみましたが、active_processハンドルは単なるヘルパープロセスであり、アクティブなアプリケーションのプロセスではないため、それぞれAPPMODEL_ERROR_NO_APPLICATIONとAPPMODEL_ERROR_NO_PACKAGEが返されます。
ウィンドウのhwndを指定してModern/Universalアプリケーションのプロセス名を取得するため、またはユニバーサルアプリのプロセス名がアクティブであることを把握するために使用するその他のAPI。
前もって感謝します!
このようなものをリバースエンジニアリングする場合は、必ずSpy ++ユーティリティを使用してください。 Visual Studioに含まれているため、Common7\Tools\spyxx_AMD64.exeに64ビットバージョンが必要です。 [検索]> [ウィンドウの検索]を使用して、ブルズアイを天気などのUWPアプリにドラッグします。
GetForegroundWindow()で見つけたウィンドウが表示され、少なくとも3つの子ウィンドウがあります。
したがって、すでに持っているコードから追加の手順を実行する必要があります。子ウィンドウを列挙して、所有者プロセスが異なるウィンドウを探す必要があります。いくつかのCコードは、あまり多くの仮定をせず、十分なエラーチェックを行わずに、可能な限りユニバーサルにしようとしています。
#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;
}
Weatherプログラムの出力:
C:\ Program Files\WindowsApps\Microsoft.BingWeather_4.5.168.0_x86__8wekyb3d8bbwe\Microsoft.Msn.Weather.exe
これは、現在のフォアグラウンドウィンドウプロセスとストアプロセス(存在する場合)に関する情報を継続的に(デスクトップ上のさまざまなウィンドウを選択して簡単にテストできるように)表示する小さなコンソールアプリアプリケーションです。
アプリは、複数のプロセスにまたがることができるウィンドウ階層を持つことができます。ここで行うのは、「Windows.UI.Core.CoreWindow」クラス名を持つ最初のサブウィンドウを検索することです。
このアプリは IAutomation API (および、#importディレクティブによって提供されるスマートポインター、スマートBSTR、およびスマートVARIANT)を使用します。標準のWindowsSDKでも同じことができると思いますが、UIAutomationはこのように非常にエレガントに使用されています。
#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;
}
実行中のプロセスのスナップショットを取得し、プロセスIDを比較して名前を引き出すことはできませんか?ここで完全なリファレンス:
https://msdn.Microsoft.com/en-us/library/windows/desktop/ms686837(v = vs.85).aspx
ただし、CreateToolhelp32Snapshot()を使用してスナップショットを修正します。
または、WTSEnumerateProcesses()とその周辺のAPIからですか?
それがWin8で機能したことはかなり確かです。それは10で壊れていますか?