2

我正在尝试编写一个程序,该程序从当前目录中的 MinGW 分发执行 make.exe 并利用其 STDOUT 数据和退出代码。我有一个句柄来处理我从中获取数据的 STDOUT,使用 CreatePipe 创建。当我在该管道上收到 ERROR_HANDLE_EOF 时,我假设该进程已退出并尝试获取其退出代码:

if(session->pid == 0) return;
HANDLE hp = OpenProcess(PROCESS_QUERY_INFORMATION |
            PROCESS_TERMINATE, TRUE, session->pid);
if(hp == NULL) {
    printf("OpenProcess(%i) failed, error: %i\n",
        session->pid, (int)GetLastError());
    return;
}

我的代码适用于我测试的所有其他 MinGW 实用程序(如 pwd、ls 等),我得到 STDOUT 和退出代码没有问题。但是当我在 make 上尝试时,上面的代码显示以下消息:

“OpenProcess(2032)失败,错误:87”

我用谷歌搜索错误代码 87,它显示“参数无效”。我看不出像 2032 这样的正进程 ID 有什么无效的。有什么想法吗?

4

3 回答 3

7

您应该使用句柄 fromCreateProcess而不是OpenProcess在 PID 上使用。

OpenProcess仅当进程对象仍然存在时才有效。如果进程对象消失了,当您调用OpenProcess时 - 结果是带有无效参数的调用。

您使用其他实用程序获得的成功要么是由于竞争条件(有时可能会失败),要么是您保持子进程的原始句柄处于打开状态。

于 2011-02-14T01:25:36.480 回答
1

为别人的目的留下小费。我设法ERROR_INVALID_PARAMETER (87)通过尝试打开来达到:

  • 一个系统进程 (0)
  • 属于线程而非进程的 ID(参考YatoDev 的帖子)。

第二种情况可能是一个问题,例如当您GetWindowThreadProcessId直接声明一个结果时,它是一个identifier of the thread that created the window,而不是它的指针参数(它为您提供请求的 PID)。

于 2020-06-16T10:41:41.453 回答
0

虽然帖子很旧:我注意到我ERROR_INVALID_PARAMETER在进程存在时得到了,但由不同的用户和/或 Windows 桌面和/或终端服务器会话拥有。

奇怪的是,该WTSEnumerateProcess()函数不会出现此错误,但要昂贵得多,尤其是在已经承受许多进程的重负载的系统上(并且调用我什至耗尽 Windows 内核资源)。

因此,不可能提供“真正的”无效参数并访问错误。我本来期望ERROR_ACCESS_DENIED的(但是作为常规/非提升用户调用的任务管理器仍然显示所有进程)。

看起来像 Windows 中的一些不一致?

于 2017-07-10T14:59:30.690 回答