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

时间:2009-03-29 00:21:14

标签: 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,表示我没有此权限行动。我的代码适用于任何常规应用程序,但不适用于窗口内置的窗口(文件浏览器)。我需要知道这个窗口何时是最前沿的。还有另一种方法吗?我尝试读取窗口标题,但只返回显示的当前目录。有什么想法吗?

2 个答案:

答案 0 :(得分:2)

我不确定为什么这不适用于资源管理器,但错误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);

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

答案 1 :(得分:1)

看起来32位进程只能在32位进程上调用GetModuleFileNameEx。如果您尝试在64位进程上调用它,则会因ERROR_PARTIAL_COPY而失败。在64位平台上,调用进程为64位,您应该能够在64位和32位进程上调用GetModuleFileNameEx。