Очевидный вопрос заключается в том, почему вы не просто используете QueryFullProcessImageName
, если вы этого хотите?Вам нужна совместимость с более старыми версиями Windows?
Ближайшим эквивалентом QueryFullProcessImageName
, доступным в XP, является, вероятно, GetModuleFileNameEx
.Я бы, вероятно, обнаружил, доступен ли QueryFullProcessImageName
, и использовал бы его, если это возможно, в противном случае вернитесь к GetModuleFileNameEx
.
Редактировать: Хотя GetModuleFileNameEx
не на 100% надежен при получении имени исполняемого файладля каждого возможного процесса он работает, по крайней мере, довольно существенную часть времени.Вот небольшой фрагмент тестового кода, который я собрал:
#include <windows.h>
#include <psapi.h>
#include <iterator>
#include <iostream>
#include <string>
#include <map>
std::string getfilename(DWORD pid) {
HANDLE process = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, false, pid);
static int winver;
char path[256]= {0};
DWORD size = sizeof(path);
if (winver==0)
winver = GetVersion() & 0xf;
#if WINVER >= 0x600
if (winver >= 6)
QueryFullProcessImageName(process, 0, path, &size);
else
#endif
if (!GetModuleFileNameEx(process, NULL, path, sizeof(path)))
strcpy(path, "Unknown");
return std::string(path);
}
typedef std::map<DWORD, std::string> win_map;
namespace std {
ostream &operator<<(ostream &os, win_map::value_type const &v) {
return os << v.first << ": " << v.second;
}
}
BOOL CALLBACK show_info(HWND window, LPARAM lParam) {
win_map &exes = *(win_map *)lParam;
DWORD pid;
GetWindowThreadProcessId(window, &pid);
exes[pid] = getfilename(pid);
return true;
}
int main() {
win_map exes;
EnumWindows(show_info, (LPARAM)&exes);
std::copy(exes.begin(), exes.end(), std::ostream_iterator<win_map::value_type>(std::cout, "\n"));
return 0;
}
Результаты быстрого теста несколько интересны.Скомпилированная как 32-битный код, версия, использующая QueryFullProcessImageName
, нашла 33 процесса с окнами верхнего уровня и нашла имена для 31 из этих исполняемых файлов.Версия, использующая GetModuleFileNameEx
, также нашла 33 процесса, но нашла имена только для 21 исполняемого файла.Однако, если я скомпилирую его как 64-битный код, либо версия найдет имена файлов для 31 из 33 исполняемых файлов (и те же самые два не будут выполнены).Учитывая частоту, с которой вы видите XP / x64, это, вероятно, не имеет большого значения, но я все же нашел это интересным.
В любом случае, даже наименее способная версия (32-битная / GMFNE) нашла имена для ~2/3 rds файлов.Хотя это, конечно, не то, на что вы надеетесь, но лучше, чем ничего.