我有一个应该启动另一个进程的函数:

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会将其用作工作缓冲区。

08-17 04:21