views:

587

answers:

1

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?

+1  A: 

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.

Michael
Thanks for the help; I appreciate it! I'm having trouble linking the code snippet. I get a linker error: LNK2019 unresolved external, symbol __imp__QueryFullProcessImageNameA@16 referenced in function .... I've included kernel32.lib. I'm developing on vista 64, if it matters. I'm using psdk 2003.
max
QueryFullProcessImageName wouldn't be in the 2003 SDK since it was introduced with Vista. If updating your SDK isn't an option, you can use LoadLibrary/GetProcAddress to get QueryFullProcessImageName.
Michael