从已运行的CMD窗口中捕获文本(VB.NET) [英] Capture Text from CMD Window That Is Already Running (VB.NET)

查看:282
本文介绍了从已运行的CMD窗口中捕获文本(VB.NET)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在此计算机上有一个几乎可以24/7运行的应用程序。它在命令提示符窗口中运行。我希望能够捕获当前显示在窗口中的所有文本。

There is an application that runs pretty much 24/7 on this computer. It is run inside a command prompt Window. I would like to be able to capture all of the text currently displayed in the window.

该应用程序已在运行(由于不相关的原因,无法从在VB中),所以我不能只是重定向过程的输出以保存文本。

The application is already running (and for unrelated reasons, can't be launched from within VB), so I can't just redirect the output of the process to save the text.

我当前的捕获文本的方法是使用以下代码:

My current method for capturing the text is with the following code:

SendKeys.SendWait("^(a)")
SendKeys.SendWait("^(a)")
SendKeys.SendWait("{enter}")

Dim CmdText As String = Clipboard.GetText
Clipboard.Clear()

上面的代码将全选命令发送到窗口(发送两次,否则不会捕获整个Windows文本)。然后按Enter键将其加载到剪贴板中。然后,我将剪贴板内容保存到变量中。它运作良好,但是主要的问题是它要求窗口处于焦点位置。

The above code sends a select all command to the window (it sends it twice, otherwise the entire windows text isn't captured). It then hits the enter key to load it into the clipboard. I then save the clipboard contents to a variable. It works well, but the major problem is that it requires the window to be in focus.

如果当前不在CMD窗口中,则是否有捕获该文本的方法?

Is there anyway to capture the text from the CMD window if it is currently out of focus?

编辑:我想我已经接近使用sendmessage / postmessage找到解决方法。这是当前的代码:

I think I'm getting close to finding a workaround using sendmessage/postmessage. Here is the current code:

Private Declare Function PostMessage Lib "user32.dll" Alias "PostMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As String) As Long

Private Const WM_CHAR As Long = &H102
Private Const VK_CONTROL = &H11
Private Const VK_RETURN = &HD

Public Function GetWindowHandle(ByVal processName As String) As IntPtr
    processName = System.IO.Path.GetFileNameWithoutExtension(processName)
    Dim p() = Process.GetProcessesByName(processName)
    Return If(p.Length > 0, p(0).MainWindowHandle, IntPtr.Zero)
End Function

Private Sub GetText()

Dim h As Long = GetWindowHandle("programname.exe")
SendMessage(h, WM_CHAR, 1, 0) 'suppose to simulate Ctrl + A
SendMessage(h, WM_CHAR, 1, 0) 'suppose to simulate Ctrl + A

PostMessage(h, WM_KEYDOWN, VK_RETURN, 0) 'sends enter key to load text into clipboard

End Sub

问题在于,它不是向命令窗口发送Ctrl + A,而是发送文本^ A。有什么想法吗?

The problem is that instead of sending Ctrl + A to the command window, it just sends the text ^A. Any ideas?

推荐答案

我写了一个名为 InputHelper ,在这里可能会派上用场。它包括执行输入模拟的不同方法,一种是将其发送到特定窗口。

I've written a library called InputHelper which could come in handy here. It includes different methods of performing input simulation, one being sending it to a specific window.


从GitHub下载:

https://github.com/Visual-Vincent/InputHelper / releases

wiki 远未完成,但是库本身包含描述其中每个方法的XML文档(当您在成员中选择一个方法或成员时,Visual Studio的IntelliSense会自动显示该文档)

Its wiki is sadly far from complete, but the library itself includes XML documentation describing every method inside it (which is automatically shown by Visual Studio's IntelliSense when you select a method or member in the members list that pops up while typing).

该库当前包含四个主要类别:

The library currently consists of four main categories:


  • InputHelper.Hooks :用于捕获系统范围内的类(有时称为 global >)鼠标和键盘输入。可以用来制作例如热键。

  • InputHelper.Hooks: Classes for capturing system-wide (some times referred to as global) mouse and keyboard input. Can be used to make for instance hot keys.

InputHelper.Keyboard >:模拟实际键盘输入/按键的方法。

InputHelper.Keyboard: Methods for simulating real keyboard input/key strokes.

InputHelper.Mouse :模拟实际鼠标输入的方法。

InputHelper.Mouse: Methods for simulating real mouse input.

InputHelper.WindowMessages :在更虚拟的级别上模拟鼠标和键盘输入的方法,例如针对特定的窗口。这利用了窗口消息(因此 SendMessage() PostMessage())。

最后提到的那是您感兴趣的一个。使用 InputHelper.WindowMessages.SendKeyPress(),您可以将特定的按键发送到您选择的窗口,或者如果省略,则发送到当前活动的窗口。

The last one mentioned would be the one of your interest. Using InputHelper.WindowMessages.SendKeyPress() you can send a specific key stroke to a window of your choice or, if omitted, the currently active window.

类似的东西应该可以工作:

Something like this should work:

Dim hWnd As IntPtr = GetWindowHandle("programname.exe")

'Send CTRL + A twice.
InputHelper.WindowMessages.SendKeyPress(hWnd, Keys.Control Or Keys.A)
InputHelper.WindowMessages.SendKeyPress(hWnd, Keys.Control Or Keys.A)

'Send ENTER.
InputHelper.WindowMessages.SendKeyPress(hWnd, Keys.Enter)

请注意,执行 Keys.Control或Keys.A 发送组合 CTRL + A ,但是在使用 Keys.Control Keys.Shift Keys.Alt (或组合其中)。使用任何其他键(例如 Keys.A或Keys.B Keys.ControlKey或Keys.A )没事。

Note that doing Keys.Control Or Keys.A sends the combination CTRL + A, however this works only when using either Keys.Control, Keys.Shift or Keys.Alt (or a combination of them). Using any other keys (for instance Keys.A Or Keys.B or Keys.ControlKey Or Keys.A) won't work.

这篇关于从已运行的CMD窗口中捕获文本(VB.NET)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆