Exu*_*One 4 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;
}
Run Code Online (Sandbox Code Playgroud)
这只是一个在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;
}
Run Code Online (Sandbox Code Playgroud)
那么,有什么想法吗?
最明显的事情是char cmdLine2[sizeof(CMDLINE)];声明一个长度等于机器指针大小的字符串。你需要strlen(CMDLINE)+1改用。同样对于appName.
请注意,第一个参数 toCreateProcess不需要是可写的。只需将字符串文字直接传递给它。不需要appName变量。
至于lpCommandLine哪个确实需要可写,最简单的方法是这样做:
char cmdline[] = "op1 op2 op3";
Run Code Online (Sandbox Code Playgroud)
这给了你一个可写的缓冲区。请注意,您不需要重复可执行文件名。
另一个问题是您尚未将所有参数初始化为CreateProcess. 例如,STARTUPINFO结构体有 19 个字段,而您只初始化了 3 个。您应该将所有结构体初始化为 0,然后填写您需要为非零的任何字段。像这样:
STARTUPINFO info = { 0 };
Run Code Online (Sandbox Code Playgroud)
对您传递的所有结构执行此操作。
你可以,也应该通过NULL对lpProcessAttributes和lpThreadAttributes参数。
这个答案是为了联系另一个原因0xc0000142- 放置在这里(即使这个问题接受了另一个答案),因为关于此错误的内管上几乎没有有用的信息 - 并且令人震惊地缺乏来自微软的关于该主题的任何有用信息 -因此,某人的互联网搜索可能会将他们带到这里。(嗯,我的就是这样。)
所以:您可以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
Run Code Online (Sandbox Code Playgroud)
0xc0000005当然,这是访问冲突,并且偏移量为 0(实际上小于的任何内容0x10000都是通过空指针的引用。
不管怎样,令人惊讶的事情(对我来说)是评估静态发生在调试器可以附加(!!)之前ImageFileExecutionOptions,所以用set 启动它甚至直接在 Visual Studio 中启动它不会让你调试这个东西!
(当然,您0xc0000142在任何 Microsoft 文档中都找不到。干得好,NT 团队!)