在 C# 中从外部应用程序获取 UI 文本

Posted

技术标签:

【中文标题】在 C# 中从外部应用程序获取 UI 文本【英文标题】:Getting UI text from external app in C# 【发布时间】:2010-09-06 07:52:59 【问题描述】:

是否可以从 C# 中的外部应用程序获取 UI 文本。

特别是,有没有办法从第三方编写的外部 Win32 应用程序的标签(我假设它是普通的 Windows 标签控件)中读取 Unicode 文本?文本在 UI 中可见,但无法通过鼠标选择。

我假设有一些可访问性 API(例如,用于屏幕阅读器)允许这样做。

编辑:目前正在考虑使用 Managed Spy App 之类的东西,但仍会感谢任何其他线索。

【问题讨论】:

【参考方案1】:

如果您只关心标准 Win32 标签,那么 WM_GETTEXT 可以正常工作,如其他答案中所述。

--

有一个可访问性 API - UIAutomation - 用于标准标签,它也在幕后使用 WM_GETTEXT。然而,它的一个优点是它可以从其他几种类型的控件获取文本,包括大多数系统控件,并且通常使用非系统控件的 UI - 包括 WPF、IE 和 Firefox 中的文本等。

// compile as:
// csc file.cs /r:UIAutomationClient.dll /r:UIAutomationTypes.dll /r:WindowsBase.dll
using System.Windows.Automation;
using System.Windows.Forms;
using System;

class Test

    public static void Main()
    
        // Get element under pointer. You can also get an AutomationElement from a
            // HWND handle, or by navigating the UI tree.
        System.Drawing.Point pt = Cursor.Position;
        AutomationElement el = AutomationElement.FromPoint(new System.Windows.Point(pt.X, pt.Y));
        // Prints its name - often the context, but would be corresponding label text for editable controls. Can also get the type of control, location, and other properties.
        Console.WriteLine( el.Current.Name );
    

【讨论】:

【参考方案2】:

如果该 unicode 文本实际上是一个带有标题的窗口,您可以通过发送 WM_GETTEXT 消息来实现。

[DllImport("user32.dll")]
public static extern int SendMessage (IntPtr hWnd, int msg, int Param, System.Text.StringBuilder text);

System.Text.StringBuilder text = new System.Text.StringBuilder(255) ;  // or length from call with GETTEXTLENGTH
int RetVal = Win32.SendMessage( hWnd , WM_GETTEXT, text.Capacity, text);

如果它只是在画布上绘制,如果您知道应用程序使用什么框架,那么您可能会很幸运。如果它使用 WinForms 或 Borland 的 VCL,您可以使用这些知识来获取文本。

【讨论】:

这也适用于标准的 win32 标签和按钮。 Interop nit:SendMessage 应该返回 IntPtr,并将 IntPtr 用于 wParam。在 WM_TEXT 的情况下可能无关紧要(尽管如果作为 64 位代码运行,不正确的 wParam 可能会成为问题?),但最好使用正确的类型,以防代码被剪切和粘贴重新调整用途。【参考方案3】:

在那篇文章中没有看到 wm_gettext 或 wm_gettextlength 的值,所以以防万一..

const int WM_GETTEXT = 0x0D;
const int WM_GETTEXTLENGTH = 0x0E;

【讨论】:

以上是关于在 C# 中从外部应用程序获取 UI 文本的主要内容,如果未能解决你的问题,请参考以下文章

如何在 C# 中从外部站点的 url 读取 PDF 文件 [关闭]

在 Unity 4.6 中从 C# 脚本创建 UI 按钮,无需任何预制件 [重复]

如何在 C# 中从位图中读取文本? [关闭]

在 C# 应用程序中从 Azure DevOps 获取构建测试结果

如何在 C# 中从 Facebook SDK 获取当前用户访问令牌?不是应用访问令牌

在 C# 中从类外部访问私有构造函数