OpenProcess 错误 87 无效参数
我正在尝试编写一个程序,该程序在当前目录中执行 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) failed, error: 87”
我在 google 上搜索错误代码 87,它显示“无效参数”。我不知道像 2032 这样的正进程 ID 可能会无效。有什么想法吗?
I'm trying to write a program which executes make.exe from MinGW distribution in the current directory and makes use of its STDOUT data and exit code. I have a handle to process STDOUT where I fetch data from, created with CreatePipe. When I get an ERROR_HANDLE_EOF on that pipe I assume the process has exited and try to get its exit code:
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;
}
My code works on all other MinGW utilities I tested (like pwd, ls, etc.), I get the STDOUT and the exit code with no problem. But when I try it on make, the above code displays the following message:
"OpenProcess(2032) failed, error: 87"
I googled for error code 87, and it says "Invalid parameter". I don't see what could be invalid about a positive process id like 2032. Any ideas?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您应该使用来自
CreateProcess
的句柄,而不是在 PID 上使用OpenProcess
。OpenProcess
仅当进程对象仍然存在时才有效。当您调用OpenProcess
时,如果流程对象已消失 - 结果是使用无效参数的调用。您使用其他实用程序获得的成功要么是由于竞争条件(有时可能会失败),要么是您使子进程的原始句柄保持打开状态。
You should use the handle from
CreateProcess
instead of usingOpenProcess
on the PID.OpenProcess
only works if the process object still exists. By the time you callOpenProcess
if the process object is gone - the result is a call with invalid parameter.The success you got with other utilities is either due to a race condition (which may fail some times) or you kept the original handle to the child process open.
为了别人的目的而留下小费。我设法通过尝试打开以下内容来达到
ERROR_INVALID_PARAMETER (87)
:当您例如从
GetWindowThreadProcessId
直接,它是创建窗口的线程的标识符
,而不是它的指针参数(它为您提供了请求的 PID)。Leaving a tip for someone else's purpose. I managed to reach the
ERROR_INVALID_PARAMETER (87)
by trying to open:The second case may be a problem when you e.g. claim a result from
GetWindowThreadProcessId
directly, which is anidentifier of the thread that created the window
, instead of its pointer parameter (which gives you requested PID).虽然帖子很旧:我注意到当进程存在但由不同的用户和/或 Windows 桌面和/或终端服务器会话拥有时,我得到了
ERROR_INVALID_PARAMETER
。奇怪的是,
WTSEnumerateProcess()
函数不会遇到此错误,但成本要高得多,特别是在一个已经处于大量进程的重负载系统上(并且调用我的甚至耗尽 Windows 内核资源)。因此,不可能造成提供的“真实”无效参数和访问错误。我本来期望的是
ERROR_ACCESS_DENIED
(但作为常规/非提升用户调用的任务管理器仍然显示所有进程)。看起来 Windows 中有些不一致?
Although the post is old: I noticed that I got
ERROR_INVALID_PARAMETER
when the process existed, but owned by different user and/or Windows desktop and/or terminal server session.Strange enough, the
WTSEnumerateProcess()
function does not suffer from this error, but is much more expensive, especially on a system that is already under heavy load with many processes (and a call my even exhaust windows kernel resources).So, it is not possible to make a 'real' invalid parameter provided and access errors. I would have expected
ERROR_ACCESS_DENIED
instead (but a task manager invoked as regular/non-elevated user still shows all processes).Look like some inconsistencies in Windows?