如何向进程发送键而不是字符?
System.Diagnostics.Process 公开了一个名为 StandardInput 的 StreamWriter,据我所知,它只接受字符。
但我还需要发送击键,并且某些击键不能很好地映射到字符。
我应该怎么办?
System.Diagnostics.Process exposes a StreamWriter named StandardInput, which accepts only characters as far as I know.
But I need to send keystrokes as well, and some keystrokes don't map well to characters.
What should I do?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您正在将输入流与控制信号混合。正如您所知,控制台进程有一个默认输入流,您可以使用 StandardInput 控制该输入流。但 Ctrl-C 和 Ctrl-Break 不是通过此流发送到进程的字符,而是进程使用注册的信号处理程序接收的控制信号,请参阅CTRL+C 和 CTRL+BREAK 信号:
要向进程发送虚假信号,您可以使用
GenerateConsoleCtrlEvent
并发送CTRL_C_EVENT
或CTRL_BREAK_EVENT
。此 API 没有 .Net 等效项,因此您必须 PInvoke 它。要从 .NET 使用它,您只需包含函数定义:
You are mixing input streams with control signals. A console process has a default input stream which you can control with the StandardInput, as you already know. But Ctrl-C and Ctrl-Break are not characters sent to the process through this stream, but instead they are instead control signals that the process receives using the registered signal handlers, see CTRL+C and CTRL+BREAK Signals:
To send fake signals to a process you can use
GenerateConsoleCtrlEvent
and send eitherCTRL_C_EVENT
orCTRL_BREAK_EVENT
. This API has no .Net equivalent, so you have to PInvoke it.To use it from .NET you simply need to include the function definition:
在 Codeplex 上找到了一个输入模拟器,它可能适合您。
我正在编写示例代码,很快就会发回此处,请记住输入模拟器与 Remus 提供的链接中的内容类似...
编辑: 我发现有有了这个限制,您绝对可以摆脱典型的 System.Windows.Forms.SendKeys.Send 方法,它确实有效!
,但是,该进程必须有显示此操作生效过程的窗口!
在您的情况下,只需找到窗口,通过 pinvoke 'SetForegroundWindow' 将其设置为活动状态,然后发送序列
^{BREAK}
,该序列将 Ctrl+Break 信号发送到进程这确实工作得很好(特别是如果该进程是命令行程序/批处理文件)。这是关于 CodeProject 的文章,它完全做到了这一点并反映了 SendKeys...我还没有粘贴一些代码来演示......编辑#2:实际上我很惊讶......因为这段代码将显示(概念证明)......它正在使用:
SendKeys
函数...我使用 Thread.Sleep 的原因是为了确保发送击键以便“推入键盘队列” “活动前台窗口”,尽管如此,它是隐藏的”撇开挑剔不谈,我知道
netStat
正在“BackgroundWorker”线程上运行,并且我直接从主 GUI 线程调用了“PostCtrlC”方法……作为证明,这是迂腐的——概念代码,但它确实表明它需要实现“ISynchronizeInvoke”以使其线程安全,除此之外......它确实有效。There's an input Simulator found here on Codeplex which may do just the job for you.
I am working on a sample code and will post back here shortly, bear in mind the Input Simulator is similar to what was found in the link supplied by Remus...
Edit: I have found that there is a limitation with this, you can definitely get away with the typical
System.Windows.Forms.SendKeys.Send
method, it does work effectively!, but, the process must haveA window showing the process for this to be effective!
In your case, it's a matter of finding the window, set it active via pinvoke 'SetForegroundWindow', and send the sequences
^{BREAK}
which sends the Ctrl+Break signal to the process which does work very well (especially if the process is a command line program/batch file). Here's an article on CodeProject that does this exactly and mirrors the SendKeys...I have yet to paste some code into this to demonstrate ....Edit#2: Actually I am quite surprised...as this code will show (proof of concept)...it is using:
FindWindow
API call, because I knew the window's title was and was somehow, able to bring it to the foreground, and using the InputSimulator to send the keystrokes to it...or use the traditional plain oldSendKeys
function...the reason I had theThread.Sleep
is to ensure that the keystrokes are sent in order to be 'pushed into the keyboard queue of the "active foreground window", which despite that, is hidden'Nitpicky aside, I know that the
netStat
is running off the 'BackgroundWorker' thread, and I directly invoked the 'PostCtrlC' method from the main GUI thread...this is pedantic as a proof-of-concept code, but it does show that it needs to implement 'ISynchronizeInvoke' to make it thread-safe, that aside...it does indeed work.您见过这个很棒的工具吗 - AutoIt。这是一个脚本工具。要发送退格键,您可以使用
Send("{BACKSPACE}")
这是一个很棒的工具,它可以帮助自动执行许多手动点击/双击等。
这与您的问题相关吗?
Have you seen this great tool - AutoIt. This is a scripting tool. To send a backspace you would use
Send("{BACKSPACE}")
This is a great tool and it can help in automating many manual clicks/double-clicks/etc.
Is this relevant to your question ?
如果您有一个可以将密钥发送到的 Windows 窗体窗口,则 SendKeys 可能是一个合适的解决方案。
对于按退格键和 Ctrl+C,应该是
If you have a Windows Forms window that you can send the keys to, then SendKeys might be an appropriate solution.
For pressing backspace and Ctrl+C, that should be