当程序可见或最小化时进程 ID 发生变化

Process ID changes when program is visible or minimized

我正在尝试获取程序的进程 ID (PID),但由于某些奇怪的原因,PID 发生了变化。当目标程序 (Alarms & Clock) 可见时,它给了我错误的 PID,而将程序最小化给了我正确的 PID。

我猜测最小化目标程序 suspends 它正在处理,从而允许读取它。但是,即使进程是 运行.

,简单地读取 PID 也不应该是一个限制。

有人知道我做错了什么吗?

目前尝试过的方法:

有一段描述问题的简洁有效的代码:

#include <iostream>
#include <Windows.h>
#include <string>

int main()
{
    std::string window_name = "Alarms & Clock"; //Feel free to replace this with another program
    HWND hwnd = FindWindowA(NULL, window_name.c_str());
    if (!hwnd)
    {
        std::cerr << "Error: Could not find window" << std::endl;
        return -1;
    }

    DWORD processID = 0;
    GetWindowThreadProcessId(hwnd, &processID);
    std::cout << "Process ID: " << processID << std::endl;
    std::cin.get();

    return 0;
}

您需要检查返回的 hwnd 值 - 您可以查看当 appcontainer 应用程序暂停时(您将其最小化 window)以及当它处于活动状态时 - 您会有所不同hwnd。对于处于 活动状态 的所有应用程序容器 - 它的主框架 window 不属于它的进程,而是属于 ApplicationFrameHost.exe 并且有A​​pplicationFrameWindowclass。但是当它最小化时 - 需要准确点击最小化按钮 - 进程 暂停 并且..但是让 运行 此代码

if (HWND hwnd = FindWindowW(0, L"Alarms & Clock"))
{
    ULONG pid, tid = GetWindowThreadProcessId(hwnd, &pid);

    DbgPrint("%x %x.%x", hwnd, pid, tid);

    WCHAR sz[MAX_PATH];
    if (GetClassName(hwnd, sz, RTL_NUMBER_OF(sz)))
    {
        DbgPrint(" [%S]", sz);
    }

    if (HANDLE hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pid))
    {
        PROCESS_EXTENDED_BASIC_INFORMATION pebi;
        if (0 <= ZwQueryInformationProcess(hProcess, ProcessBasicInformation, &pebi, sizeof(pebi), 0))
        {
            DbgPrint(" Suspended=%x, flags(%x)", pebi.IsFrozen, pebi.Flags);
        }
        ULONG len = RTL_NUMBER_OF(sz);
        if (QueryFullProcessImageNameW(hProcess, 0, sz, &len))
        {
            DbgPrint(" %S", sz);
        }

        CloseHandle(hProcess);
    }

    DbgPrint("\n");
}

我得到了 2 个状态的下一个输出:

1902e6 510.155c [Windows.UI.Core.CoreWindow] Suspended=1, flags(58) C:\Program Files\WindowsApps\Microsoft.WindowsAlarms_10.1605.1742.0_x64__8wekyb3d8bbwe\Time.exe
740414 574.934 [ApplicationFrameWindow] Suspended=0, flags(8) C:\Windows\System32\ApplicationFrameHost.exe

我能够使用 GCC 5.3 在 Win/10 上重新生成问题。我使用 "Calculator" 应用程序对其进行了测试。当应用程序的 window 被 not 最小化时,我得到了属于 ApplicationFrameHost.exe 的 PID = 14440,但是,我得到了 PID = 1936 当 calc 的 window 最小化时正确。

这是因为 "Calculator" 是 tablet 应用程序,而不是 desktop 应用程序。 桌面 无论window 是否最小化,应用程序都会提供正确的 PID。

我认为 对您有用。

ApplicationFrameHost.exe似乎是一个处理许多子应用程序的应用程序容器。需要额外的代码来检索您要查找的确切子应用程序 pid。

基于该页面,我编写了这段代码并且对我有用,但是,您可能需要改进它。

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;
}

void Show_PID()
{
    Sleep(1000);
    std::string window_name = "Calculator"; 
    HWND hwnd = FindWindowA(NULL, window_name.c_str());
    windowinfo info = { 0 };
    GetWindowThreadProcessId(hwnd, &info.ownerpid);
    info.childpid = info.ownerpid;
    EnumChildWindows(hwnd, EnumChildWindowsCallback, (LPARAM)&info);
    std::cout << "Process ID: " << info.childpid << std::endl;
}

int main()
{
    for (int i = 0; i < 9; ++i)
    {
        Show_PID();
    }

    return 0;
}