【问题标题】:System() to start a process, but using CreateProcess fails?System() 启动进程,但使用 CreateProcess 失败?
【发布时间】:2016-02-11 21:20:55
【问题描述】:

所以,奇怪的问题,我正在尝试创建一个进程,然后恢复它,主要是探索 Windows API。我注意到如果我这样做:

system("C:\\Windows\\System32\\calc.exe");

它会打开一个计算器 exe,但是如果我尝试使用 CreateProcessA 做同样的事情,我会得到这个:

STARTUPINFO starting_info;
PROCESS_INFORMATION process_info;

// let's try and make a process
if (!CreateProcessA(NULL, "C:\\Windows\\System32\\calc.exe", NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &starting_info, &process_info)) {
    return;
}
// resume thread
NtResumeThread(process_info.hThread, NULL);

由于某种原因,这在大多数情况下会在“创建”进程时抛出 0xc0000142 错误,否则它就会失败。

发生了什么事?

【问题讨论】:

  • STARTUPINFOA starting_info = {sizeof(starting_info)};
  • @ChristopherOicles 为什么需要这样做?
  • @Link 请考虑阅读文档
  • 需要初始化结构的大小,因为指针可以寻址 STARTUPINFO 或 STARTUPINFOEX 对象。系统从指示大小的cb值知道传递了什么对象。
  • Marius 是正确的,初始化也将 cb 之后的字段清零。此外,您正在显式调用 ANSI 版本的 CreateProcess,因此您还希望显式使用 STARTUP_INFO 的 ANSI 版本,以防万一这最终以 Unicode 构建结束。 PROCESS_INFORMATION 没有不同的 ANSI 和 Wide 版本,因为它不涉及字符串。另一件事,命令行字符串应该是可写的,而不是像你的文字那样的常量——但是我不确定在什么情况下传递常量字符串实际上会导致问题。

标签: c++ windows process


【解决方案1】:

请参阅以下 MSDN 示例代码以创建进程: https://msdn.microsoft.com/en-us/library/windows/desktop/ms682512(v=vs.85).aspx

您需要将sipi 结构清零,同时设置

si.cb = sizeof(si);

最后,关闭进程和线程句柄。

CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);

【讨论】:

  • 流程信息结构体不需要初始化
  • @DavidHeffernan 你是对的。进程信息结构是一个输出参数。初始化它 (PROCESS_INFORMATION pi = { 0 };) 不是必须的。
猜你喜欢
  • 2014-12-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-28
  • 2015-04-16
  • 2020-08-08
  • 1970-01-01
相关资源
最近更新 更多