来自正在运行的进程 Win32Api 的管道输出(stdout)
我需要使用 Windows API 从已经运行的进程获取(或通过管道传输)输出。
基本上我的应用程序应该允许用户选择一个窗口来传输输入,并且所有输入都将显示在控制台中。稍后我还会研究如何在 stderr 上获取管道。
重要提示:我没有使用 CreateProcess() 或其他方式启动该进程。该进程已经在运行,我所拥有的只是该进程的句柄(从 GetWindowThreadProcessId() 返回)。
I need to get (or pipe) the output from a process that is already running, using the 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.
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()).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
在不造成任何不良影响的情况下,最干净的方法是使用挂钩,如果您使用 Adam 暗示的将现有标准输出句柄与您自己的句柄交换的方法,则可能会发生这种情况。
如果您将一个线程注入到现有应用程序中,并将对 WriteFile 的调用与拦截的版本交换,该版本将首先为您提供正在写入的内容的副本(通过句柄、源等进行过滤),然后将其传递给真正的 ::WriteFile造成的伤害。或者,您可以通过仅交换 printf 或软件正在使用的任何调用来拦截更高层的调用(显然需要一些实验)。
然而,亚当说这不是你想做的事,他说得很对。这是最后的手段,所以在走这条线之前要非常非常仔细地考虑!
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.
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).
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!
在搜索该主题时发现了 MS 的这篇文章。
http://support.microsoft.com/kb/190351
管道输入和输出的概念Unix 很简单,似乎没有什么理由让它在 Windows 上如此复杂。 ——卡尔
Came across this article from MS while searching on the topic.
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
无论你想做什么,你都做错了。如果您正在与拥有源代码的程序进行交互,请为您的 IPC 创建定义的接口:创建套接字、命名管道、Windows 消息传递、共享内存段、COM 服务器或任何您喜欢的 IPC 机制。不要尝试将 IPC 移植到不打算进行 IPC 的程序上。
您无法控制该进程的标准输出是如何设置的,并且它不是您可以乱搞的。它由其父进程创建并移交给子进程,从那里开始,它就由子进程控制。 你不能进去更换别人家的地毯房子。
甚至不要考虑进入该进程,尝试
CloseHandle
其标准输出,并CreateFile
指向您的管道的新标准输出。这会导致灾难,并会导致古怪的行为和“不可能的”崩溃。即使您可以做您想做的事情,什么会如果两个程序执行此操作会发生吗?
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.
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, andCreateFile
a new stdout pointing to your pipe. That's a recipe for disaster and will result in quirky behavior and "impossible" crashes.Even if you could do what you wanted to do, what would happen if two programs did this?