CreateProcess异常(kernel32.lib)

时间:2013-11-12 11:36:24

标签: c++ c winapi win32-process

运行此代码时出现异常:

STARTUPINFO si;
PROCESS_INFORMATION pi;

ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));

CreateProcess(NULL, L"program.dat", NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);

// Wait until child process exits.
WaitForSingleObject( pi.hProcess, INFINITE );

// Close process and thread handles. 
CloseHandle( pi.hProcess );
CloseHandle( pi.hThread );

我在WaitForSingleObject上得到了异常。

谢谢:)

2 个答案:

答案 0 :(得分:6)

尽可能明确地在documentation ::

中说明
  

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

你的L"program.dat"属于这条规则。将字符串复制到某个WCHAR变量中并传递它。

答案 1 :(得分:4)

我可以使用您的代码重现异常。我认为问题是CreateProcess的第二个arg是进/出的。该文件指出:

  

系统在命令行字符串中添加一个终止空字符,以将文件名与参数分开。这会将原始字符串分为两个字符串以进行内部处理。

请参阅CreateProcess function

第二个arg不能指向只读内存。

使用Visual Studio调试器并单步执行汇编程序代码,陷阱确实是由Kernel32中的_CreateProcessInternal函数引起的,该函数试图将0x写入L“program.dat”的末尾,作为字符串常量,它位于“不可写”部分。

使用以下代码:

wchar_t * pCommandLine = L"program.dat";
wchar_t CommandLine[ 64 ];
wcscpy( CommandLine,  pCommandLine );
CreateProcess(NULL, CommandLine, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);

并且异常将消失。

使用“program.dat”创建子进程?!?那是另一个故事。