Для тех, кто озадачен получением списка процессов в ОС Windows поделюсь своими изысканиями. Как было сказано в двух постах выше: - функция ZwQuerySystemInformation не рекомендуема к использованию Microsoft'ом
- CreateToolhelp32Snapshot не работает с 64-разрядными процессами
Остальные способы, приведённые в указанной статье показались мне несколько невзрачными. Приведу код, с помощью которого можно решить поставленную задачу (а именно, получение списка процессов с PID, а значит и со всей сопутствующей информацией)
| Код | // Оказалось, что для некоторых процессов в Windows Vista (н/р csrss.exe) // необходимо получить привелегии SE_DEBUG_NAME. HANDLE htoken; if(OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &htoken)) { TOKEN_PRIVILEGES tkp; LookupPrivilegeValueW(NULL, SE_DEBUG_NAME, &tkp.Privileges[0].Luid); tkp.PrivilegeCount = 1; tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; AdjustTokenPrivileges(htoken, FALSE, &tkp, 0, NULL, 0); CloseHandle(htoken); }
std::wofstream output(L"processes.log"); if(!output.is_open()) { std::cerr << "Can't open log file\n"; system("pause"); return 1; } WTS_PROCESS_INFO *ppinfo; DWORD count; WTSEnumerateProcesses(WTS_CURRENT_SERVER_HANDLE, 0, 1, &ppinfo, &count);
const DWORD len = 256; wchar_t username[len]; wchar_t domainname[len]; DWORD dname_len = len; DWORD uname_len = len; SID_NAME_USE snu; for(DWORD i = 0; i < count; i++) { output << "[" << ppinfo[i].pProcessName << "]\n" << "PID = " << ppinfo[i].ProcessId << "\nUser = "; if(LookupAccountSid(NULL, ppinfo[i].pUserSid, username, &uname_len, domainname, &dname_len, &snu)) output << username << "\nDomain = " << domainname; else output << "<Unknown>\nDomain = <Unknown>"; output << std::endl << std::endl; dname_len = len; uname_len = len; }
WTSFreeMemory(ppinfo); output.close();
|
Данный код запишет все процессы в файл в виде
| Код | [имя_программы.exe] PID = 500 User = имя_пользователя Domain = доменное имя
|
P.S. пример не оптимизирован, но наглядно демонстрирует работу. |