windows 来自运行进程 Win32Api 的管道输出(stdout)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7603808/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Pipe output(stdout) from running process Win32Api
提问by David
I need to get (or pipe) the output from a process that is already running, using the windows api.
我需要使用 windows api 从已经运行的进程中获取(或管道)输出。
Basically my application should allow the user to select a window to pipe the input from, and all input will be displayed in a console. I would also be looking on how to get a pipe on stderr later on.
基本上我的应用程序应该允许用户选择一个窗口来输入输入,并且所有输入都将显示在控制台中。稍后我还将研究如何在 stderr 上获取管道。
Important: I did not start the process using CreateProcess() or otherwise. The process is already running, and all I have is the handle to the process (returned from GetWindowThreadProcessId()).
重要提示:我没有使用 CreateProcess() 或其他方式启动进程。该进程已经在运行,我所拥有的只是该进程的句柄(从 GetWindowThreadProcessId() 返回)。
采纳答案by Adam Rosenfield
Whatever you're trying to do, you're doing it wrong. If you're interacting with a program for which you have the source code, create a defined interface for your IPC: create a socket, a named pipe, windows messaging, shared memory segment, COM server, or whatever your preferred IPC mechanism is. Do not try to graft IPC onto a program that wasn't intending to do IPC.
无论你想做什么,你都做错了。如果您正在与拥有源代码的程序进行交互,请为您的 IPC 创建一个定义的接口:创建一个套接字、一个命名管道、Windows 消息传递、共享内存段、COM 服务器或任何您喜欢的 IPC 机制。不要试图将 IPC 移植到不打算进行 IPC 的程序上。
You have no control over how that process's stdout was set up, and it is not yours to mess with. It was created by its parent process and handed off to the child, and from there on out, it's in control of the child. You don't go in and change the carpets in somebody else's house.
您无法控制该进程的标准输出是如何设置的,也不是您可以处理的。它由其父进程创建并传递给子进程,从那时起,它由子进程控制。 你不会进去换别人家的地毯。
Do not even think of going into that process, trying to CloseHandle
its stdout, and CreateFile
a new stdout pointing to your pipe. That's a recipe for disaster and will result in quirky behavior and "impossible" crashes.
甚至不要考虑进入该过程,尝试使用CloseHandle
其标准输出和CreateFile
指向您的管道的新标准输出。这是灾难的秘诀,将导致古怪的行为和“不可能的”崩溃。
Even if you could do what you wanted to do, what would happen if two programs did this?
回答by Mahmoud Al-Qudsi
The cleanest way of doing this without causing any ill effects, such that may occur if you used the method Adam implied of swapping the existing stdout handle with your own, is to use hooking.
在不引起任何不良影响的情况下执行此操作的最干净方法是使用挂钩,如果您使用 Adam 暗示的将现有 stdout 句柄交换为您自己的方法,则可能会发生这种情况。
If you inject a thread into the existing application and swap calls to WriteFile with an intercepted version that will first give you a copy of what's being written (filtered by handle, source, whatever) then pass it along to the real ::WriteFile with no harm done. Or you can intercept the call higher up by only swapping out printf or whichever call it is that the software is using (some experimentation needed, obviously).
如果您将一个线程注入现有应用程序并使用截获版本交换对 WriteFile 的调用,该版本将首先为您提供正在写入的内容的副本(按句柄、源等过滤),然后将其传递给真正的 ::WriteFile,没有造成的伤害。或者,您可以通过仅交换 printf 或软件正在使用的任何调用来拦截更高层的调用(显然需要进行一些实验)。
HOWEVER, Adam is spot-on when he says this isn't what you want to do. This is a last resort, so think very, very carefully before going down this line!
然而,当亚当说这不是你想做的事情时,他是正确的。这是最后的手段,所以在走这条线之前要非常非常仔细地考虑!
回答by Karl
Came across this article from MS while searching on the topic. http://support.microsoft.com/kb/190351
在搜索该主题时从 MS 看到了这篇文章。 http://support.microsoft.com/kb/190351
The concept of piping input and output on Unix is trivial, there seems no great reason for it to be so complex on Windows. - Karl
在 Unix 上管道输入和输出的概念是微不足道的,在 Windows 上似乎没有理由如此复杂。- 卡尔