winapi - Vista下如何获取进程文件名?

标签 winapi windows-vista

我有一个帮助残障人士的应用程序。为了工作,它跟踪当前在前台的窗口。通常,我使用此函数来获取进程可执行文件。

bool GetWindowProcessExe2(HWND hwnd, wxString& process_exe)  
                       //LPTSTR buf, DWORD size)
{
DWORD result = 0;
DWORD pid = 0;
GetWindowThreadProcessId(hwnd, &pid);
if (HANDLE process =
    OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid))
{
  char buff[512];
  LPTSTR pbuff = buff;
  result = GetModuleFileNameEx(process, 0, pbuff, 512);
  if(result == 0)
  {
    //failed.
    wxLogError("GetModuleFileNameEx failed with error code %d", GetLastError());
  }
  CloseHandle(process);
  process_exe = fromCString(pbuff);
}

return result > 0 ? true : false;

不幸的是,如果前台窗口是 Vista 文件管理器窗口(当您单击“开始”->“计算机”时打开的窗口),GetModuleFileNameEx() 将失败,错误代码为 299,表明我没有有执行此操作的权限。我的代码适用于任何常规应用程序,但不适用于内置窗口(文件资源管理器)的窗口。我需要知道这个窗口何时处于最前沿。还有另一种方法吗?我尝试阅读窗口标题,但它只返回显示的当前目录。有什么想法吗?

最佳答案

我不确定为什么这对资源管理器不起作用,但错误 299 是 ERROR_PARTIAL_COPY,这意味着尝试从资源管理器中读取模块名称失败。

在 Vista 上,首选 QueryProcessImageFileName 并且仅使用 PROCESS_QUERY_LIMITED_INFORMATION 打开进程 - 您的代码将适用于更多情况。

WCHAR exeName[512];
DWORD cchExeName = 512;
HANDLE process = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, 0, pid);
QueryFullProcessImageName(process, 0, exeName, &cchExeName);

编辑:我还得到了 ERROR_PARTIAL_COPY,你的代码在 64 位上运行,但只有当查询过程是 32 位时。 64 位/64 位工作正常。

关于winapi - Vista下如何获取进程文件名?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/693858/

相关文章:

windows - 如何使我的程序在 Windows Vista 和 Windows 7 中运行?

c++ - 如何确定两个 Win32 API 句柄代表同一个对象?

c++ - 如何处理 std::thread 中的 PostMessage 线程消息?

windows-7 - tortoisesvn 上下文菜单和 Windows 7/Vista UAC

C# 从服务运行 Windows 窗体应用程序(在 Vista 中)

c++ - 无法在 64 位 Vista 上运行使用 MinGW Dev-C++ 编译的 C 程序

windows-vista - OpenInputDesktop() 确定安全/登录桌面

winapi - 使 MessageBox 保持在其他窗口之上

c++ - Hook WM_SETTEXT 消息

go - Syscall()与Call()?