Windows 8/10中活动窗口的进程名称

时间:2015-09-02 18:02:50

标签: c++ windows winapi accessibility win-universal-app

以下示例已可靠地返回与活动窗口关联的进程的名称,但不能与较新的现代/通用应用程序一起使用,因为它返回帮助程序进程的名称 WWAHost.exe 和Windows 10上的 ApplicationFrameHost.exe ,而不是应用程序的名称。

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可用于获取活动的通用应用程序的活动进程? / p>

还尝试使用GetApplicationUserModelId()和GetPackageFullName()没有成功,因为它们分别返回APPMODEL_ERROR_NO_APPLICATION和APPMODEL_ERROR_NO_PACKAGE,因为active_process句柄只是辅助进程而不是活动应用程序的进程。

在给定窗口的hwnd时,用于获取Modern / Universal应用程序的进程名称的任何其他API,或以其他方式确定通用应用程序的进程名称是活动的。

提前致谢!

4 个答案:

答案 0 :(得分:17)

当你想对这样的东西进行逆向工程时,一定要使用Spy ++实用程序。包含在Visual Studio中,您需要Common7 \ Tools \ spyxx_amd64.exe中的64位版本。使用搜索>查找窗口并将靶心拖动到UWP应用程序,如Weather。

您将看到使用GetForegroundWindow()找到的窗口,它至少有3个子窗口:

  • ApplicationFrameTitleBarWindow
  • ApplicationFrameInputSinkWindow
  • Windows.Core.UI.CoreWindow,这是UWP应用程序的主机窗口和您感兴趣的应用程序。右键单击它并选择“属性”,“进程”选项卡,单击“进程ID”。这会将您带到您想知道的真实所有者流程。

因此,您只需要从已有的代码中进行额外的步骤,您只需枚举子窗口并查找具有不同所有者进程的窗口。一些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;
}

天气计划的输出:

  

C:\ Program Files \ WindowsApps \ Microsoft.BingWeather_4.5.168.0_x86__8wekyb3d8bbwe \   Microsoft.Msn.Weather.exe

答案 1 :(得分:10)

这是一个小型控制台应用程序应用程序,连续(因此您可以轻松地在桌面上选择不同的窗口进行测试)显示有关当前前台窗口进程和存储过程的信息(如果有)。

应用可以有一个可以跨越多个进程的窗口层次结构。我在这里做的是搜索具有'Windows.UI.Core.CoreWindow'类名的第一个子窗口。

此应用程序使用UIAutomation API(以及#import指令提供的智能指针,智能BSTR和智能VARIANT)。我想你可以用标准的Windows SDK做同样的事情,但我觉得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;
}

答案 2 :(得分:2)

通过比较进程ID无法获取正在运行的进程的快照并将名称拉出来吗? 完整参考:

https://msdn.microsoft.com/en-us/library/windows/desktop/ms686837(v=vs.85).aspx

但您使用CreateToolhelp32Snapshot()修复了快照。

或者来自WTSEnumerateProcesses()和周围的API?

很确定它在Win 8中有效。它在10中被打破了吗?

答案 3 :(得分:-2)

从Win10周年更新开始ApplicationFrameHost子窗口返回除UWP应用程序之外的任何内容。它在relogon之后只能在平板电脑模式下工作。