Createprocess和0xc0000142错误

时间:2012-02-04 16:23:54

标签: c++ windows createprocess

我有以下测试代码:

#define CMDLINE ".\\dummyFolder\\dummyProc.exe op1 op2 op3"

int main(int argc, char **argv) {

STARTUPINFO info;
info.cb = sizeof(STARTUPINFO);
info.lpReserved = NULL;
info.cbReserved2 = 0;
info.lpReserved2 = NULL;

PROCESS_INFORMATION processInfo;

SECURITY_ATTRIBUTES procAttr;
procAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
procAttr.lpSecurityDescriptor = NULL;
procAttr.bInheritHandle = false;

SECURITY_ATTRIBUTES threadAttr;
procAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
procAttr.lpSecurityDescriptor = NULL;
procAttr.bInheritHandle = false;

bool handlersInheritable = true;

char cmdLine2[sizeof(CMDLINE)];
strcpy(cmdLine2, CMDLINE);

char AppName[sizeof(".\\dummyFolder\\dummyProc.exe")];
strcpy(AppName, ".\\dummyFolder\\dummyProc.exe");


if (CreateProcess(AppName, cmdLine2, &procAttr, &threadAttr,
        handlersInheritable, 0, NULL, NULL, &info, &processInfo)) {

    //::WaitForMultipleObjects(procQty, handlers, waitForAll, waitInterval);
    CloseHandle(processInfo.hProcess);
    CloseHandle(processInfo.hThread);
    CloseHandle(info.hStdError);
    CloseHandle(info.hStdInput);
    CloseHandle(info.hStdOutput);
} else {
    std::cout << "Returned: " << GetLastError() << std::endl;
}

std::cout << "Exiting main process" << std::endl;

return 0;
}

这只是用于在Windows中创建进程的测试代码。问题是,当我启动“dummyProc.exe”时,我得到一个0xc0000142错误。

进程dummyProc.exe从命令行运行正常,但不能从代码中运行。

如果有帮助,这是dummyProc代码:

int main(int argc, char **argv) {


std::cout << "Working!!!!" << std::endl << "Receivedi: " << std::endl;

for (int i = 0; i < argc; ++i)
    std::cout << argv[i] << std::endl;


return 0;
}

那么,有什么想法吗?

2 个答案:

答案 0 :(得分:4)

最明显的事情是char cmdLine2[sizeof(CMDLINE)];声明一个长度等于机器指针大小的字符串。您需要使用strlen(CMDLINE)+1代替。同样适用于appName

请注意,CreateProcess的第一个参数不需要是可写的。只需将字符串文字直接传递给它。不需要appName变量。

对于需要可写的lpCommandLine,这样做最简单:

char cmdline[] = "op1 op2 op3";

这为您提供了可写缓冲区。请注意,您无需重复执行文件名。

另一个问题是您尚未将所有参数初始化为CreateProcess。例如,STARTUPINFO结构有19个字段,并且只初始化3.您应该将所有结构初始化为0,然后填写您需要非零的任何字段。像这样:

STARTUPINFO info = { 0 };

对你传递的所有结构都这样做。

您可以而且应该为NULLlpProcessAttributes参数传递lpThreadAttributes

答案 1 :(得分:1)

这个答案是关于0xc0000142的另一个原因 - 放在这里(即使这个问题接受了另一个答案)因为关于这个错误的关于intertubes的信息非常少 - 而且令人震惊缺少 任何有关微软主题的有用信息 - 所以某人的互联网搜索可能会在这里得到它们。 (好吧,我的确如此。)

所以:你可以获得The application was unable to start correctly (0xc0000142)来启动用C ++编写的进程,你可以通过静态对象的构造函数中的空指针来访问它。 (在我的例子中,它是在静态对象的构造函数的初始化器中。)

您对此的提示将是应用程序日志中的事件(事件ID 1000源“应用程序错误”),其中包含类似于以下内容的行:

Faulting module name: unknown, version: 0.0.0.0, time stamp: 0x00000000
Exception code: 0xc0000005
Fault offset: 0x0000000000000000
当然,

0xc0000005是访问冲突,偏移量为0(实际上小于0x10000的任何值都是通过空指针的引用。

无论如何,令我惊讶的是(对我而言)评估静态发生之前调试器可以附加(!!)所以使用ImageFileExecutionOptions设置启动它甚至直接在Visual Studio中启动它不要让你调试这个东西!!

(当然,在任何Microsoft文档中都不会找到0xc0000142。做得好,NT团队!)