C++ 为什么CreateProcess API调用会导致内存访问冲突?

C++ 为什么CreateProcess API调用会导致内存访问冲突?,c++,winapi,createprocess,C++,Winapi,Createprocess,我有一个应该启动另一个进程的函数: 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, T

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

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“访问冲突读取位置0xFFFFFFFFFFFFFF”中遇到异常。我知道有几个常见的错误可能会导致这种情况:

  • 不一致的呼叫约定。我正在使用stdcall
  • 编码问题。我将字符串存储为宽字符
  • 问题发生在x64和x86版本中
  • 当我尝试创建其他Windows进程时会出现问题
我做错了什么

编辑:将
cmd.c_str()
转换为
(LPWSTR)
,这实际上不是问题,该部分看起来很好。我需要初始化STARTUPINFO结构:
STARTUPINFO={0}

那是演员阵容。一个伟大的经验法则是“发现演员,你发现错误”

这是真的<必须向code>CreateProcessW
传递一个可写字符串。这意味着,没有文字,也没有
c_str()
result

从文件中:

此函数的Unicode版本,
CreateProcessW
,可以修改此字符串的内容。因此,此参数不能是指向只读内存(例如常量变量或文字字符串)的指针。如果此参数是常量字符串,则函数可能会导致访问冲突

传递一个真正的非-
常量
指针,不要玩隐藏-
常量
&cmd[0]
应该可以工作,这保证是一个可写字符串。为了超级安全,请将
wstring
容量增加到所需容量之外,因为
CreateProcessW
将使用它作为工作缓冲区

那是演员阵容。一个伟大的经验法则是“发现演员,你发现错误”

这是真的<必须向code>CreateProcessW传递一个可写字符串。这意味着,没有文字,也没有
c_str()
result

从文件中:

此函数的Unicode版本,
CreateProcessW
,可以修改此字符串的内容。因此,此参数不能是指向只读内存(例如常量变量或文字字符串)的指针。如果此参数是常量字符串,则函数可能会导致访问冲突


传递一个真正的非-
常量
指针,不要玩隐藏-
常量
&cmd[0]
应该可以工作,这保证是一个可写字符串。为了超级安全,请将
wstring
容量增加到所需容量之外,因为
CreateProcessW
将使用它作为工作缓冲区。

不完全重复,因为存在另一个错误访问冲突写入位置。。在这里访问读取位置。cmd.c_str()实际上是可写内存,它不指向字符串文字(它复制到分配的内存)。错误的真正来源是什么-未初始化
STARTUPINFOW信息
同样,如果我们有确切的应用程序路径,为什么不将其作为
CreateProcessW
的第一个参数传递呢?在本例中(显式路径),2参数可以是只读字符串,因为当我们有path时,不需要为临时隔离应用程序名解析和修改命令行
STARTUPINFO={sizeof(info)}必须为空。若你们有确切的应用程序路径,那个么最好将它作为一个参数传递给创建流程。即使您只有名称-最好先直接调用
SearchPath
并将结果传递给1个参数。不完全重复,因为存在另一个错误访问冲突写入位置。。在这里访问读取位置。cmd.c_str()
实际上是可写内存,它不指向字符串文字(它复制到分配的内存)。错误的真正来源是什么-未初始化
STARTUPINFOW信息
同样,如果我们有确切的应用程序路径,为什么不将其作为
CreateProcessW
的第一个参数传递呢?在本例中(显式路径),2参数可以是只读字符串,因为当我们有path时,不需要为临时隔离应用程序名解析和修改命令行
STARTUPINFO={sizeof(info)}必须为空。若你们有确切的应用程序路径,那个么最好将它作为一个参数传递给创建流程。即使您只有名称-最好先直接调用
SearchPath
并将结果传递给1个参数。
BOOL hR = CreateProcessW(NULL, (LPWSTR)cmd.c_str(), NULL, NULL, TRUE, 0, NULL, NULL, &info, &processInfo);
                                  ^^^^^