CppUtils/Utils/Process.cpp
2025-06-05 10:06:43 +08:00

338 lines
10 KiB
C++

#include "Process.h"
#include "Convert.h"
#include <winternl.h>
#pragma comment(lib, "ntdll.lib")
Process::Process(int _id)
{
this->Id = _id;
}
Process::Process(int _id, std::wstring _processName)
{
this->Id = _id;
this->ProcessName = _processName;
}
Process Process::CurrentProcess()
{
return Process((int)GetCurrentProcessId());
}
Process Process::FromHandle(HANDLE handle)
{
return Process((int)GetProcessId(handle));
}
Process Process::FromWindow(HWND hwnd)
{
return Process((int)GetWindowThreadProcessId(hwnd, NULL));
}
Process Process::FromThread(HANDLE handle)
{
return Process((int)GetProcessIdOfThread(handle));
}
std::vector<Process> Process::GetProcessesByName(const std::string _name)
{
std::wstring name = Convert::string_to_wstring(_name);
std::vector<Process> result = std::vector<Process>();
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnapshot == INVALID_HANDLE_VALUE) return result;
PROCESSENTRY32W pe = { sizeof(pe) };
if (Process32FirstW(hSnapshot, &pe))
{
do
{
if (_wcsicmp(name.c_str(), pe.szExeFile) == 0)
{
result.push_back(Process(pe.th32ProcessID,Convert::string_to_wstring(_name)));
}
} while (Process32NextW(hSnapshot, &pe));
}
CloseHandle(hSnapshot);
return result;
}
std::vector<Process> Process::GetProcesses()
{
std::vector<Process> result = std::vector<Process>();
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnapshot == INVALID_HANDLE_VALUE) return result;
PROCESSENTRY32W pe = { sizeof(pe) };
if (Process32FirstW(hSnapshot, &pe))
{
do
{
result.push_back(Process(pe.th32ProcessID, pe.szExeFile));
} while (Process32NextW(hSnapshot, &pe));
}
CloseHandle(hSnapshot);
return result;
}
HWND Process::FindMainWindow(int processId)
{
HWND hwnd = NULL;
auto tmp = std::pair<int, HWND>(processId, hwnd);
EnumWindows([](HWND wnd, LPARAM param)->BOOL
{
auto p = (std::pair<int, HWND>*)param;
DWORD processId;
if (GetWindowThreadProcessId(wnd, &processId) && processId == p->first)
{
p->second = wnd;
SetLastError(ERROR_SUCCESS);
return FALSE;
}
return TRUE;
}, (LPARAM)&tmp);
return hwnd;
}
std::vector<HWND> Process::GetForms(int processId)
{
std::vector<HWND> result = std::vector<HWND>();
auto tmp = std::pair<int, std::vector<HWND>&>(processId, result);
EnumWindows([](HWND wnd, LPARAM param)->BOOL
{
auto p = (std::pair<int, std::vector<HWND>&>*)param;
DWORD processId;
if (GetWindowThreadProcessId(wnd, &processId) && processId == p->first)
{
p->second.push_back(wnd);
}
return TRUE;
}, (LPARAM)&tmp);
return result;
}
std::vector<HWND> Process::Forms()
{
return GetForms(this->Id);
}
Process Process::Start(const std::string fileName, const std::string arguments, const std::string workingDirectory)
{
STARTUPINFOA si = { sizeof(si) };
PROCESS_INFORMATION pi;
if (!CreateProcessA(fileName.c_str(), (LPSTR)arguments.c_str(), NULL, NULL, FALSE, 0, NULL, workingDirectory.c_str(), &si, &pi))
{
return Process(0);
}
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
return Process(pi.dwProcessId);
}
HWND Process::MainWindowHandle()
{
return FindMainWindow(this->Id);
}
std::string Process::MainWindowTitle()
{
HWND hwnd = this->MainWindowHandle();
if (hwnd == NULL) return "";
int length = GetWindowTextLength(hwnd);
if (length == 0) return "";
std::vector<char> buffer(length + 1);
GetWindowTextA(hwnd, buffer.data(), length + 1);
return std::string(buffer.data());
}
HANDLE Process::ParentProcessId()
{
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, this->Id);
if (hProcess == NULL) return NULL;
PROCESS_BASIC_INFORMATION pbi;
ULONG returnLength;
NTSTATUS status = NtQueryInformationProcess(hProcess, ProcessBasicInformation, &pbi, sizeof(pbi), &returnLength);
CloseHandle(hProcess);
if (status != 0) return NULL;
return (HANDLE)pbi.UniqueProcessId;
}
int Process::SessionId()
{
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, this->Id);
if (hProcess == NULL) return NULL;
DWORD sessionId;
ProcessIdToSessionId(this->Id, &sessionId);
CloseHandle(hProcess);
return sessionId;
}
int Process::BasePriority()
{
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, this->Id);
if (hProcess == NULL) return NULL;
int priority = GetPriorityClass(hProcess);
CloseHandle(hProcess);
return priority;
}
std::string Process::MachineName()
{
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, this->Id);
if (hProcess == NULL) return "";
std::vector<char> buffer(MAX_PATH);
DWORD size = MAX_PATH;
QueryFullProcessImageNameA(hProcess, 0, buffer.data(), &size);
CloseHandle(hProcess);
std::string path = std::string(buffer.data());
int index = path.find("\\\\");
if (index == -1) return "";
return path.substr(2, index - 2);
}
int Process::ExitCode()
{
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, this->Id);
if (hProcess == NULL) return NULL;
DWORD exitCode;
GetExitCodeProcess(hProcess, &exitCode);
CloseHandle(hProcess);
return exitCode;
}
bool Process::HasExited()
{
return this->ExitCode() != STILL_ACTIVE;
}
MODULEINFO Process::MainModule()
{
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, this->Id);
if (hProcess == NULL) return MODULEINFO();
HMODULE hMod;
DWORD cbNeeded;
if (EnumProcessModules(hProcess, &hMod, sizeof(hMod), &cbNeeded))
{
MODULEINFO mi;
GetModuleInformation(hProcess, hMod, &mi, sizeof(mi));
CloseHandle(hProcess);
return mi;
}
CloseHandle(hProcess);
return MODULEINFO();
}
void Process::Kill()
{
HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, this->Id);
if (hProcess == NULL) return;
TerminateProcess(hProcess, 0);
CloseHandle(hProcess);
}
std::vector<MODULEENTRY32> Process::Modules()
{
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, this->Id);
if (hProcess == NULL) return std::vector<MODULEENTRY32>();
std::vector<MODULEENTRY32> result = std::vector<MODULEENTRY32>();
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, this->Id);
if (hSnapshot == INVALID_HANDLE_VALUE) return result;
MODULEENTRY32 me = { sizeof(me) };
if (Module32First(hSnapshot, &me))
{
do
{
result.push_back(me);
} while (Module32Next(hSnapshot, &me));
}
CloseHandle(hSnapshot);
CloseHandle(hProcess);
return result;
}
std::vector<HANDLE> Process::Threads()
{
std::vector<HANDLE> result = std::vector<HANDLE>();
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, this->Id);
if (hSnapshot == INVALID_HANDLE_VALUE) return result;
THREADENTRY32 te = { sizeof(te) };
if (Thread32First(hSnapshot, &te))
{
do
{
if (te.th32OwnerProcessID == this->Id)
{
HANDLE hThread = OpenThread(THREAD_QUERY_INFORMATION, FALSE, te.th32ThreadID);
if (hThread != NULL)
{
result.push_back(hThread);
}
}
} while (Thread32Next(hSnapshot, &te));
}
CloseHandle(hSnapshot);
return result;
}
long long Process::NonpagedSystemMemorySize()
{
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, this->Id);
if (hProcess == NULL) return NULL;
PROCESS_MEMORY_COUNTERS pmc;
GetProcessMemoryInfo(hProcess, &pmc, sizeof(pmc));
CloseHandle(hProcess);
return pmc.QuotaNonPagedPoolUsage;
}
long long Process::PagedMemorySize()
{
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, this->Id);
if (hProcess == NULL) return NULL;
PROCESS_MEMORY_COUNTERS pmc;
GetProcessMemoryInfo(hProcess, &pmc, sizeof(pmc));
CloseHandle(hProcess);
return pmc.QuotaPagedPoolUsage;
}
long long Process::PeakPagedMemorySize()
{
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, this->Id);
if (hProcess == NULL) return NULL;
PROCESS_MEMORY_COUNTERS pmc;
GetProcessMemoryInfo(hProcess, &pmc, sizeof(pmc));
CloseHandle(hProcess);
return pmc.PeakPagefileUsage;
}
long long Process::PeakVirtualMemorySize()
{
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, this->Id);
if (hProcess == NULL) return NULL;
PROCESS_MEMORY_COUNTERS pmc;
GetProcessMemoryInfo(hProcess, &pmc, sizeof(pmc));
CloseHandle(hProcess);
return pmc.PeakWorkingSetSize;
}
long long Process::PeakWorkingSet()
{
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, this->Id);
if (hProcess == NULL) return NULL;
PROCESS_MEMORY_COUNTERS pmc;
GetProcessMemoryInfo(hProcess, &pmc, sizeof(pmc));
CloseHandle(hProcess);
return pmc.PeakWorkingSetSize;
}
long long Process::VirtualMemorySize()
{
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, this->Id);
if (hProcess == NULL) return NULL;
PROCESS_MEMORY_COUNTERS pmc;
GetProcessMemoryInfo(hProcess, &pmc, sizeof(pmc));
CloseHandle(hProcess);
return pmc.WorkingSetSize;
}
bool Process::WaitForInputIdle(int milliseconds)
{
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | SYNCHRONIZE, FALSE, this->Id);
if (hProcess == NULL) return false;
bool result = ::WaitForInputIdle(hProcess, milliseconds) != 0;
CloseHandle(hProcess);
return result;
}
bool Process::WaitForExit(int milliseconds)
{
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | SYNCHRONIZE, FALSE, this->Id);
if (hProcess == NULL) return false;
bool result = ::WaitForSingleObject(hProcess, milliseconds) != 0;
CloseHandle(hProcess);
return result;
}
long long Process::TotalProcessorTime()
{
FILETIME lpCreationTime, lpExitTime, lpKernelTime, lpUserTime;
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, this->Id);
if (hProcess == NULL) return NULL;
GetProcessTimes(hProcess, &lpCreationTime, &lpExitTime, &lpKernelTime, &lpUserTime);
CloseHandle(hProcess);
return (lpKernelTime.dwHighDateTime << 32) | lpKernelTime.dwLowDateTime;
}
long long Process::UserProcessorTime()
{
FILETIME lpCreationTime, lpExitTime, lpKernelTime, lpUserTime;
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, this->Id);
if (hProcess == NULL) return NULL;
GetProcessTimes(hProcess, &lpCreationTime, &lpExitTime, &lpKernelTime, &lpUserTime);
CloseHandle(hProcess);
return (lpUserTime.dwHighDateTime << 32) | lpUserTime.dwLowDateTime;
}