我想将所有winapi与Standart C ++一起使用。如何通过地址传递输出?看起来 o_processName 。 GetModuleFileNameExW 函数参数3需要wchar_t类型。我需要将其转换为wstring类型。当我搜索时,可能是将内存地址传递给 GetModuleFileNameExW 而不是类型。
void GetProcessNameById(DWORD i_processId, std::wstring *o_processName)
{
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, i_processId);
if (hProcess != NULL)
{
if (GetModuleFileNameExW(hProcess, NULL, &o_processName, MAX_PATH))
{
CloseHandle(hProcess);
}
}
}
答案 0 :(得分:2)
您不能将std::wstring
(或任何C ++容器)直接 传递给Win32 API函数。 Win32 API是使用C接口编写的,因此它对C ++类型一无所知。因此,调用API时必须使用C语义。
在您的示例中,您可以分配一个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);
}
如果需要,您可以在using std::unique_ptr
in C++11 and later to ensure the HANDLE
is closed automatically when it goes out of scope之前更进一步。
最后,您应该使用GetProcessImageFileNameW()
而不是GetModuleFileNameExW()
:
要检索用于远程进程的主要可执行模块的名称,请使用
GetProcessImageFileName
或QueryFullProcessImageName
函数。与使用NULL模块句柄调用GetModuleFileNameEx
函数相比,这更有效,更可靠。
此外,由于GetProcessImageFileName()
仅需要PROCESS_QUERY_LIMITED_INFORMATION
个访问权限,因此与PROCESS_QUERY_INFORMATION | PROCESS_VM_READ
相比,您更有可能获得访问权限,尤其是对于系统/受限制的进程。