С++ Получение списка процессов и путей к exe файлам
March 23rd, 2010 Begemot Posted in Программирование
Вот неожиданно понадобилось получить список из всех запущенных exe файлов. Xотя казалось бы зачем оно такое может быть надо в simple end-user utility for storing clipboard history, но оказалось что надо. Пришлось изобретать велосипед, что бы труды не пропадали – решил опубликовать.
Вкратце получаем снимок всех процессов в системе CreateToolhelp32Snapshot, итерируясь по нему, для каждого процесса делаем снимок его модулей и получаем полный путь к ехе файлу. Если полный путь не нужен, а достаточно только имени файла – то вторую часть делать не нужно.
Теперь просто код, он простой, написан для универсальности с использованием stl.
wstring GetFullPathForProcess(DWORD pid)
{
// Take a snapshot of all modules in the specified process.
HANDLE hModuleSnap = NULL;
hModuleSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid);
if (hModuleSnap == INVALID_HANDLE_VALUE) return _T("");
MODULEENTRY32 me32 = {0};
me32.dwSize = sizeof(MODULEENTRY32);
if (!::Module32First(hModuleSnap, &me32))
{
::CloseHandle(hModuleSnap);
return _T("");
}
::CloseHandle(hModuleSnap);
return wstring(me32.szExePath);
}
ProcessMappingType GetAllRunningApplication()
{
ProcessMappingType m;
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnap != INVALID_HANDLE_VALUE)
{
PROCESSENTRY32 proc;
proc.dwSize = sizeof(PROCESSENTRY32);
if (Process32First(hSnap, &proc))
{
m[proc.szExeFile] = GetFullPathForProcess(proc.th32ProcessID);
while (Process32Next(hSnap, &proc))
m[proc.szExeFile] = GetFullPathForProcess(proc.th32ProcessID);
}
else wxFAIL_MSG(wxString::Format("Error Process32First: %i", GetLastError()));
::CloseHandle(hSnap);
}
else wxFAIL_MSG(wxString::Format("Error Load ToolHelp: %i", GetLastError()));
return m;
}
Все, с вас конфетка 🙂
P.S. И еще, хорошие люди просили сослаться на скандинавский аукцион в Киеве, дык мне не трудно 🙂 А вы верите в подобное?
March 23rd, 2010 at 7:50
Ха-ха-ха… а ты проверял, как это работает, если запускать не из студии?
А под Windows Vista/7 под пользовательским аккаунтом?
короткое имя ты, может быть и получишь, но вот полный путь тебе не получить…
В XP нужно установить привелегию SeDebugPrivilege, а под остальным ОС-ями так просто не сделаешь… 🙁
March 23rd, 2010 at 8:06
птьфу ты так меня пугать после выхода релиза и за когда я уже вставал что бы спать идти, а тут твой коммент и я вдруг понимаю что я действительно забыл проверить под 7кой:)
Проверил, под 7кой и под ХР, под обычным пользователем работает отлично, теперь можно и спать 🙂
March 24th, 2010 at 6:56
Это работает для процессов текущего юзера. а для системных процессов работать не будет.
Кстати, если пишешь, что “код с использованием stl”, то зачем wx-овский код сюда приплетать?
И цикл while лучше заменить на do … while…
И ещё – если будут 2 процесса с одинаковым именем, но разными путями – твой код не будет правильно работать…
March 24th, 2010 at 11:30
С пунтой воюешь? 😉
March 24th, 2010 at 4:57
Может я и придираюсь,
Но при “wstring GetFullPathForProcess()” делать “return _T(“”);” – не совсем правильно с идеологической точки зрения. По идее должно быть “return L””;” – _tchar это не всегда wide char.
По поводу “!::Module32First(hModuleSnap, &me32)” – а что остаётся в me32, когда функция возвращает ошибку? Если мусор, то понятно, а если me32 остаётся в начальном состоянии, то можно просто пропустить:
::Module32First(hModuleSnap, &me32);
::CloseHandle(hModuleSnap);
return wstring(me32.szExePath);//ибо вернётся пустая строка при ошибке
Да и HANDLE’ы просится завернуть во врапперы, чтобы не писать CloseHandle каждый раз ручками.
March 24th, 2010 at 7:14
1. Ну прости мне старому засранцу, то что забыл два wxFAIL выкинуть из версии для блога:) Я там еще забыл include нужный добавить..
2. да согласен, мой ляп
3. угу, тоже согласен – но для моей задачи это вполне нормально, поэтому так получилось.
March 24th, 2010 at 7:15
Не, ее я уже давно победил и она мне не сильно мешала 🙂 Это для решения других проблем.
March 24th, 2010 at 7:16
Konstantin, да в принципе со всем согласен, не идеально у меня, но такой задачи и не стояло 🙂
March 26th, 2010 at 9:46
using namespace это нехорошо :\
March 26th, 2010 at 2:27
Смотря где… в cpp файле нормально.
правда у меня в precompiled header вообще, но я планирую исправить :)))
March 26th, 2010 at 4:27
🙂