Windows – How to get the process filename under Vista

winapiwindows-vista

I have an application that aids people with disabilities. In order to work, it tracks the what window is currently in the foreground. Normally, I use this function to get process executable.

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;

}

Unfortunately, if the foreground window is the Vista file manager window (the window that opens when you click Start->Computer), GetModuleFileNameEx() fails with error code 299 which says I don't have privileges for this action. My code works for any regular application but not for the windows built in window (the file explorer). I need to know when this window is forefront. Is there another way to do it? I tried reading the window title but that just returns the current directory being shown. Any ideas?

Best Answer

I'm not sure why this isn't working for explorer, but error 299 is ERROR_PARTIAL_COPY, meaning that attempting to read the module name out of explorer is failing.

On Vista, prefer QueryProcessImageFileName and only open the process with PROCESS_QUERY_LIMITED_INFORMATION - your code will work in more cases.

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

EDIT: I also got ERROR_PARTIAL_COPY with your code running on 64-bit, but only when the querying process was 32-bit. 64-bit/64-bit worked fine.