我有一个应该启动另一个进程的函数:
DWORD WINAPI StartCalc(LPVOID lpParam) {
STARTUPINFOW info;
PROCESS_INFORMATION processInfo;
std::wstring cmd = L"C:\\Windows\\System32\\calc.exe";
BOOL hR = CreateProcessW(NULL, (LPWSTR)cmd.c_str(), NULL, NULL, TRUE, 0, NULL, NULL,
&info, &processInfo);
if (hR == 0) {
DWORD errorMessageID = ::GetLastError();
printf("Error creating process\n");
return 1;
}
return 0;
}
我在ntdll.dll“访问冲突读取位置0xFFFFFFFFFFFFFFFF”中得到异常。我知道可能会导致以下一些常见错误:
调用约定不一致。我正在使用__stdcall
编码问题。我将字符串存储为宽字符
该问题同时发生在x64和x86版本中
当我尝试创建其他Windows进程时会发生问题
我究竟做错了什么?
编辑:这实际上不是将
cmd.c_str()
转换为(LPWSTR)
的问题,该部分似乎还不错。我需要初始化STARTUPINFO结构:STARTUPINFO info = { 0 };
最佳答案
BOOL hR = CreateProcessW(NULL, (LPWSTR)cmd.c_str(), NULL, NULL, TRUE, 0, NULL, NULL, &info, &processInfo);
^^^^^
那是演员阵容。经验法则是“发现演员表,发现错误”。
这是真的
CreateProcessW
必须传递一个可写字符串。这意味着,没有文字,也没有c_str()
结果。从文档中:
此函数的Unicode版本
CreateProcessW
可以修改此字符串的内容。因此,该参数不能是指向只读存储器的指针(例如const变量或文字字符串)。如果此参数是常量字符串,则该函数可能会导致访问冲突。传递一个真实的非
const
指针,不要播放“ const
隐藏”。 &cmd[0]
应该可以工作,保证可以写一个字符串。为了超级安全,将wstring
的容量增加到超出所需的范围,因为CreateProcessW
会将其用作工作缓冲区。