c# - 从 Windows 应用程序的文本框中抓取文本

标签 c# c++ winforms winapi screen-scraping

是否可以从包含在单独的可执行文件中的文本框中抓取文本?我有一个具有调试窗口的应用程序。调试窗口生成详细日志。但是,日志永远不会保存在任何地方,只能在应用程序内查看。如果应用程序生成异常,我想给自己发电子邮件,知道已生成异常,这样我就可以跳进去检查一下。还有一个复制文本框的按钮,所以我在考虑使用 Spy++ 来获取命令信息。但是,我不知道从那里去哪里。非常感谢任何指点。

我更愿意在 .NET 中使用 C#,但如果我需要使用 C++,我会。

更新:

根据评论,我尝试执行以下操作:

Private Declare Function GETWINDOWTEXT Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Integer, ByVal lpString As String, ByVal cch As Integer) As Integer
Private Declare Function SetForegroundWindow Lib "user32.dll" (ByVal hwnd As Integer) As Integer
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindow As String) As IntPtr
Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Integer, ByVal hWnd2 As Integer, ByVal lpsz1 As String, ByVal lpsz2 As String) As Integer
Private Declare Ansi Function SendMessage Lib "user32.dll" Alias "SendMessageA" (ByVal hwnd As Integer, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As String) As Integer
Private Const WM_GETTEXT As Short = &HDS
Private Const WM_GETTEXTLENGTH As Short = &HES

Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
    Dim hwnd As Integer = FindWindowEx(0, 0, "MyAppForm", "Hello World")

    If Not hwnd = 0 Then
        SetForegroundWindow(hwnd)

        'Dim LabelEx As Integer = FindWindowEx()
        Dim TextBoxEx As Integer = FindWindowEx(hwnd, 0, "MyAppTextBox", vbNullString)
        Dim txtLength As Long = SendMessage(TextBoxEx, WM_GETTEXTLENGTH, CInt(0), CInt(0)) + 1
        Dim txtBuff As String = Space(txtLength)
        Dim txtValue As Long = SendMessage(TextBoxEx, WM_GETTEXT, txtLength, txtBuff)

        MsgBox(txtBuff)
    End If
End Sub

但是,我似乎找不到文本框控件的句柄。当我枚举所有窗口时,我只看到一个 TextBox 对象,但在整个枚举过程中我多次看到父对象。如何获取指向窗口内控件的指针?

更新 2:

我已经上传了一个示例 Windows 应用程序来显示我尝试访问的应用程序类型。除了文本框之外,我还试图获取两个标签的值。文本框是最重要的。示例 Win 应用程序位于:http://www.mediafire.com/file/172r2xapj7p4f2f/StatusSimulator.zip

最佳答案

文本抓取是通过无障碍接口(interface)完成的。对于托管代码,您可以使用 System.Windows.Automation 命名空间中的类。如果您已经有了窗口句柄,那么提取文本很简单:

AutomationElement.FromHandle(hwnd)
                 .GetCurrentPropertyValue(ValuePattern.ValueProperty) as string;

(有点困惑,因为问题被标记为 C#,而您要求的是 C# 解决方案,但您的代码示例是在 VB 中。)

关于c# - 从 Windows 应用程序的文本框中抓取文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8374531/

相关文章:

c# - 将常量映射到列表填充和查找的资源字符串

c# - 如何反序列化复选框值的 JSON 数据?

c# - 具有多级相关表的数据集

c++ - 无法确定循环是如何放置的

c# - dot net 是否有像 IEnumerable 这样带有 Count 属性的接口(interface)?

c++ - Thrift:是否可以仅使用 C++ Thrift 库进行序列化?

c++ - 使用 Matlab Coder 将 Matlab m 文件转换为 C/C++ 代码,包括 mex 文件 (mxArray)

c# - 在 C# (winform .net) 中使用 .c 文件

c# - 如何使用 Ctrl+v 在文本框中启用粘贴

c# - 不使用媒体播放器播放视频[Winform]