Вы не можете передать std::wstring
(или любой контейнер C ++) напрямую в функцию Win32 API. Win32 API написан с интерфейсом C, поэтому он ничего не знает о типах C ++. Таким образом, вы должны использовать семантику C при вызове API.
В вашем примере вы можете выделить буфер стиля C WCHAR[]
для получения имени файла, а затем назначить этот буфер вашему std::wstring
:
void GetProcessNameById(DWORD i_processId, std::wstring *o_processName) {
WCHAR szFileName[MAX_PATH];
DWORD dwLength = 0;
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, i_processId);
if (hProcess != NULL) {
dwLength = GetModuleFileNameExW(hProcess, NULL, szFileName, MAX_PATH);
CloseHandle(hProcess);
}
o_processName->assign(szFileName, dwLength);
}
В качестве альтернативы, если вы хотите использовать контейнер C ++, вы должны предварительно выделить его и затем передать его внутренний буфер данных в API:
void GetProcessNameById(DWORD i_processId, std::wstring *o_processName) {
std::wstring wFileName;
wFileName.resize(MAX_PATH);
DWORD dwLength = 0;
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, i_processId);
if (hProcess != NULL) {
dwLength = GetModuleFileNameExW(hProcess, NULL, &wFileName[0], MAX_PATH); // or wFileName.data() in C++17 and later
CloseHandle(hProcess);
}
o_processName->assign(wFileName.c_str(), dwLength);
}
void GetProcessNameById(DWORD i_processId, std::wstring *o_processName) {
std::vector<WCHAR> vecFileName(MAX_PATH, 0);
DWORD dwLength = 0;
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, i_processId);
if (hProcess != NULL) {
dwLength = GetModuleFileNameExW(hProcess, NULL, &vecFileName[0], MAX_PATH); // or vecFileName.data() in C++11 and later
CloseHandle(hProcess);
}
o_processName->assign(&vecFileName[0], dwLength); // or vecFileName.data()
}
void GetProcessNameById(DWORD i_processId, std::wstring *o_processName) {
std::array<WCHAR, MAX_PATH> arrFileName;
DWORD dwLength = 0;
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, i_processId);
if (hProcess != NULL) {
dwLength = GetModuleFileNameExW(hProcess, NULL, arrFileName.data(), MAX_PATH);
CloseHandle(hProcess);
}
o_processName->assign(arrFileName.data(), dwLength);
}
Если вы хотите, вы можете сделать этот шаг дальше, , используя std::unique_ptr
в C ++ 11 и более поздних версиях, чтобы гарантировать, что HANDLE
автоматически закрывается, когда выходит из области действия .
И, наконец, вы должны использовать GetProcessImageFileNameW()
вместо GetModuleFileNameExW()
:
Чтобы получить имя основного исполняемого модуля для удаленного процесса, используйте функцию GetProcessImageFileName
или QueryFullProcessImageName
. Это более эффективно и надежно, чем вызов функции GetModuleFileNameEx
с дескриптором модуля NULL.
Кроме того, поскольку GetProcessImageFileName()
требует только PROCESS_QUERY_LIMITED_INFORMATION
прав доступа, которые вы, скорее всего, сможете получить, чем PROCESS_QUERY_INFORMATION | PROCESS_VM_READ
прав, особенно для системных / ограниченных процессов.