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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18661/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-01 09:01:27  来源:igfitidea点击:

Getting UI text from external app in C#

提问by dbkk

Is it possible to get UI text from an external application in C#.

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

In particular, is there a way to read Unicode text from a label (I assume it's a normal Windows label control) from an external Win32 app that was written by a 3rd party? The text is visible, but not selectable by mouse in the UI.

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

I assume there is some accessibility API (e.g. meant for screen readers) that allows this.

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

Edit: Currently looking into using something like the Managed Spy Appbut would still appreciate any other leads.

编辑:目前正在考虑使用托管间谍应用程序之类的东西,但仍然会感谢任何其他线索。

回答by Lars Truijens

You could do it if that unicode text is actually a window with a caption by sending a WM_GETTEXTmessage.

如果该 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);

If it is just painted on the canvas you might have some luck if you know what framework the application uses. If it uses WinForms or Borland's VCL you could use that knowledge to get to the text.

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

回答by sieben

didn't see the values for wm_gettext or wm_gettextlength in that article, so just in case..

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

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

回答by BrendanMcK

If you just care about the standard Win32 label, then WM_GETTEXTwill work fine, as outlined in the other answers.

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

--

——

There is an accessibility API - UIAutomation- for standard labels, it too uses WM_GETTEXT behind the scenes. One advantage to it, however, is that it can get text from several other types of controls, including most system controls, and often UI using non-system controls - including WPF, text in IE and Firefox, and others.

有一个可访问性 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 );
    }
}