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

时间:2017-06-02 05:52:25

标签: c++ windows visual-studio winapi window

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

我猜测最小化目标程序suspends它的过程,从而允许它被读取。但是,即使进程正在运行,简单地读取PID也不应该是一个限制。

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

目前尝试的方法:

  • 进入管理模式
  • 编译为64位
  • 编译为32位

是一段工作,简洁的代码,描绘了这个问题:

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

2 个答案:

答案 0 :(得分:2)

我能够使用GCC 5.3在Win / 10上重新生成问题。我用&#34;计算器&#34;测试了它。应用程序。当应用程序的窗口最小化时,我得到PID = 14440属于 ApplicationFrameHost.exe ,但是,当计算结果时,我得到了PID = 1936。 s窗口最小化。

这是因为&#34;计算器&#34;是平板电脑应用,而不是桌面应用。无论窗口是否最小化,桌面应用程序都能提供正确的PID。

我认为this SO post会对你有用。

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

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

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

答案 1 :(得分:1)

您需要检查返回的 hwnd 值 - 您可以查看当appcontainer应用程序暂停时(您将窗口最小化)并且当它处于活动状态时 - 您有不同的 hwnd 。对于处于活动状态的所有应用容器 - 它的主框架窗口不属于它进程,而属于 ApplicationFrameHost.exe 并且具有 ApplicationFrameWindow 类。但是当它最小化时 - 需要完全点击最小化按钮 - 进程暂停和..但是让我们运行此代码

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