#include <Tlhelp32.h> void ListModule(DWORD pid) { HANDLE processSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid); MODULEENTRY32 me32; me32.dwSize = sizeof(MODULEENTRY32); if (Module32First(processSnap, &me32)) { do { wcout <<me32.dwSize <<endl; // Need to set before use. wcout <<me32.th32ProcessID <<endl; // The identifier of the process whose modules are to be examined. wcout <<me32.modBaseAddr <<endl; // The base address of the module in the context of the owning process. wcout <<me32.modBaseSize <<endl; // The size of the module, in bytes. wcout <<me32.hModule <<endl; // A handle to the module in the context of the owning process. wcout <<me32.szModule <<endl; // The module name. wcout <<me32.szExePath <<endl; // The module path. } while (Module32Next(processSnap, &me32)); } CloseHandle(processSnap); } void ListAllProcesses() { HANDLE processSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL); PROCESSENTRY32 pe32; pe32.dwSize = sizeof(PROCESSENTRY32); if (Process32First(processSnap, &pe32)) { do { wcout <<pe32.dwSize <<endl; // Need to set before use. wcout <<pe32.th32ProcessID <<endl; // Process ID. wcout <<pe32.cntThreads <<endl; // The number of execution threads started by the process. wcout <<pe32.th32ParentProcessID <<endl; // The identifier of the process that created this process (its parent process). wcout <<pe32.pcPriClassBase <<endl; // The base priority of any threads created by this process. wcout <<pe32.szExeFile <<endl; // The name of the executable file for the process. } while (Process32Next(processSnap, &pe32)); } CloseHandle(processSnap); } void ListAllThreads() { HANDLE processSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, NULL); THREADENTRY32 te32; te32.dwSize = sizeof(THREADENTRY32); if (Thread32First(processSnap, &te32)) { do { wcout <<te32.dwSize <<endl; // Need to set before use. wcout <<te32.th32ThreadID <<endl; // Thread ID. wcout <<te32.th32OwnerProcessID <<endl; // The ID of the process that created the thread. wcout <<te32.tpBasePri <<endl; // Thread base priority. 0 is lowest, 31 is highest. } while (Thread32Next(processSnap, &te32)); } CloseHandle(processSnap); }
#include "stdafx.h" #include <Tlhelp32.h> #include <iostream> #include <iomanip> #include <vector> #include <map> #include <string> using namespace std; struct ProcessInfo { struct ThreadInfo { DWORD th32ThreadID; DWORD tpBasePri; // Thread base priority. 0 is lowest, 31 is highest. }; typedef vector<pair<wstring, wstring>> ModuleInfos;// '.first' is path, '.second' is filename. typedef vector<ThreadInfo> ThreadInfos; // Key is process ID, value see struct ProcessInfo::ThreadInfo. DWORD th32ProcessID; DWORD th32ParentProcessID; // The identifier of the process that created this process (its parent process). DWORD cntThreads; // The number of execution threads started by the process. DWORD pcPriClassBase; // The base priority of any threads created by this process. wstring szExePath; // The full path of the executable file for the process. wstring szExeFile; // The name of the executable file for the process. ModuleInfos modules; ThreadInfos threads; }; ProcessInfo::ModuleInfos GetModuleInfos(const DWORD pid) { HANDLE moduleSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid); if (moduleSnapshot == INVALID_HANDLE_VALUE) { throw L""; } // Retrieve modules and threads info. ProcessInfo::ModuleInfos moduleInfos; MODULEENTRY32 me32 = {}; me32.dwSize = sizeof(MODULEENTRY32); if (Module32First(moduleSnapshot, &me32)) { do { moduleInfos.push_back(make_pair(me32.szExePath, me32.szModule)); } while (Module32Next(moduleSnapshot, &me32)); } CloseHandle(moduleSnapshot); return moduleInfos; } multimap<DWORD, ProcessInfo::ThreadInfo> GetAllThreadInfos() { HANDLE threadSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); if (threadSnapshot == INVALID_HANDLE_VALUE) { throw L""; } // Retrieve threads info. multimap<DWORD, ProcessInfo::ThreadInfo> allThreadInfos; THREADENTRY32 te32 = {}; te32.dwSize = sizeof(THREADENTRY32); if (Thread32First(threadSnapshot, &te32)) { do { ProcessInfo::ThreadInfo threadInfo = {}; threadInfo.th32ThreadID = te32.th32ThreadID; threadInfo.tpBasePri = te32.tpBasePri; allThreadInfos.insert(make_pair(te32.th32OwnerProcessID, threadInfo)); } while (Thread32Next(threadSnapshot, &te32)); } CloseHandle(threadSnapshot); return allThreadInfos; } vector<ProcessInfo> GetAllProcessInfos() { vector<ProcessInfo> processInfos; HANDLE processSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (processSnapshot == INVALID_HANDLE_VALUE) { throw L""; } // Get process info. PROCESSENTRY32 pe32; pe32.dwSize = sizeof(PROCESSENTRY32); if (Process32First(processSnapshot, &pe32)) { do { ProcessInfo processInfo = {}; processInfo.th32ProcessID = pe32.th32ProcessID; processInfo.th32ParentProcessID = pe32.th32ParentProcessID; processInfo.cntThreads = pe32.cntThreads; processInfo.pcPriClassBase = pe32.pcPriClassBase; try { processInfo.modules = GetModuleInfos(pe32.th32ProcessID); // This value must be evaluated before 'szExePath' & 'szExeFile'. } catch (...) { continue; } processInfo.szExePath = processInfo.modules.begin()->first; processInfo.szExeFile = processInfo.modules.begin()->second; processInfo.modules.erase(processInfo.modules.begin()); // Erase the image path and filename from module information. processInfos.push_back(processInfo); } while (Process32Next(processSnapshot, &pe32)); // Retrieve all threads information. multimap<DWORD, ProcessInfo::ThreadInfo> allThreadInfos; try { allThreadInfos = GetAllThreadInfos(); } catch (...) {} // Map the threads to corresponding process. for (vector<ProcessInfo>::iterator it = processInfos.begin(); it != processInfos.end(); ++it) { ProcessInfo::ThreadInfos threads; for (multimap<DWORD, ProcessInfo::ThreadInfo>::iterator jt = allThreadInfos.equal_range(it->th32ProcessID).first; jt != allThreadInfos.equal_range(it->th32ProcessID).second; ++jt) { threads.push_back(jt->second); } it->threads = threads; } }//if CloseHandle(processSnapshot); return processInfos; } void Output(const vector<ProcessInfo> &processInfos, wostream &wos) { // Save output stream state. wostream::fmtflags oldFmt = wos.flags(); // Every process. wos <<left; for (vector<ProcessInfo>::const_iterator it = processInfos.begin(); it != processInfos.end(); ++it) { // Process information. wos <<setw(15) <<it->szExeFile <<L'\t' <<setw(40) <<it->szExePath <<L'\t' <<setw(5) <<it->th32ProcessID <<endl; // Every threads in the process. for (vector<ProcessInfo::ThreadInfo>::const_iterator jt = it->threads.begin(); jt != it->threads.end(); ++jt) { wos <<L"\t--->" <<setw(5) <<jt->th32ThreadID <<endl; } } // Restore stream state. wos.setstate(oldFmt); } void _tmain(int argc, TCHAR *argv[]) { vector<ProcessInfo> processInfos = GetAllProcessInfos(); Output(processInfos, wcout); return; }