Как я могу получить имя файла процесса под Vista? - PullRequest
3 голосов
/ 29 марта 2009

У меня есть приложение, которое помогает людям с ограниченными возможностями. Для работы он отслеживает, какое окно в данный момент находится на переднем плане. Обычно я использую эту функцию, чтобы получить исполняемый файл процесса.

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 ]

2 голосов
/ 29 марта 2009

Я не уверен, почему это не работает для проводника, но ошибка 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-бит работал нормально.

1 голос
/ 30 июля 2012

Похоже, что 32-битный процесс может вызывать GetModuleFileNameEx только для 32-битных процессов. Если вы попытаетесь вызвать его в 64-разрядных процессах, произойдет сбой с помощью ERROR_PARTIAL_COPY. На 64-разрядной платформе вызовите процесс 64-разрядным, и вы сможете вызывать GetModuleFileNameEx как в 64-разрядных, так и в 32-разрядных процессах.

...