【发布时间】:2021-11-25 16:38:47
【问题描述】:
我正在尝试制作一个应用程序,该应用程序仅在调用 dll 时才会运行,此时聚焦的窗口与给定的值具有相同的路径。话虽如此,下面的代码将被添加到一个 dll 中,该 dll 将具有一个以路径值作为参数的函数,如果满足条件,则返回 true,否则返回 false。我遇到的问题是我似乎找不到获取焦点窗口路径的方法,以下代码总是返回一个空字符串。而且我不能简单地使用窗口的标题,因为有些应用程序是的,标题是静态的,比如Task Manager,但是还有其他的标题是改变的,比如Windows Explorer 根据用户的位置改变它的标题in. 我需要改变什么?
以下代码仅用作测试,因为稍后这是我需要的基础,我只需在path 变量上添加一个比较,并基于此返回真或假:
#include "Windows.h";
#include <iostream>
#include <chrono>
#include <thread>
using namespace std;
int main() {
// 2 seconds delay to have time to switch windows
std::this_thread::sleep_for(std::chrono::milliseconds(2000));
HWND hWnd = GetForegroundWindow();
int length = GetWindowTextLength(hWnd);
wchar_t* title = new wchar_t[length];
GetWindowTextW(hWnd, title, length);
DWORD id;
GetWindowThreadProcessId(hWnd, &id);
wchar_t* path = new wchar_t[MAX_PATH];
HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, id);
GetModuleFileNameW((HMODULE)hProc, path, MAX_PATH);
CloseHandle(hProc);
wcout << "ID: " << id << " | Title: " << title << " | Path: " << path << endl << endl;
return 1;
}
输出示例:ID: 2536 | Title: Task Manage | Path:
【问题讨论】:
-
您错误地使用了 GetModuleFilename。它返回当前进程中模块的文件名,它采用 HMODULE,而不是 HPROCESS。这不是为了获取有关另一个进程的信息。
-
你可能想要
GetModuleFileNameEx。您可能还会发现GetProcessImageFileName或QueryFullProcessImageName很有趣。 (现在 MSDN 文档由于某种原因返回 404,但它仍在 Google 缓存中) -
不幸的是,您在其他线程中建议的内容是针对 C# 的,而这和 C++ 都不是我通常使用的,C++ 仅用于当我真正需要在 Java 中无法完成的事情时,并且我需要一个本机功能。现在至于
GetModuleFileNameEx,它不允许我使用它,它被标记为undefined。 -
QueryFullProcessImageNameA确实有效,它给了我我想要的东西(对于某些人来说,它确实需要以Admin运行,例如Task Manager),但是当它出现时我注意到了一个问题对于浏览器,它在那里失败。但我怀疑这是问题所在,因为他们创建了很多实例,而不仅仅是一个说firefox.exe或edge.exe。GetWindowTextW和GetWindowThreadProcessId仍然适用于浏览器,但不适用于QueryFullProcessImageNameA。