无法从其他应用程序(窗口)获取文本

时间:2016-08-18 01:04:03

标签: c# text extract

我正在尝试从其他应用程序中提取文本。这个应用程序现在可能是简单的,我只是想让它工作(现在)。

我使用的代码:

IntPtr MytestHandle = new IntPtr(0x00788600);
HandleRef hrefHWndTarget = new HandleRef(null, MytestHandle);

我使用以下方法调用此代码:

0x00788600

其中{{1}}是我正在运行的其中一个应用程序的示例(我100%确定这是主窗口句柄)。

我需要从"其他"中的一个文本框中获取文本。应用程序,但是当我使用我的代码时,它每次都返回一个空字符串

建议?

2 个答案:

答案 0 :(得分:1)

我无法看到您的代码有任何错误。我建议检查你的手柄是否正确。

但是,为了获取TextBox的文本,您必须使用实际控件的句柄。 MainWindowHandle只返回表单标题。

我创建了一个虚拟应用程序" WindowsFormsApplication1"其中包含一些控件,并使用以下代码获取所有文本:

[Flags]
internal enum SendMessageTimeoutFlags : uint
{
    SMTO_NORMAL = 0x0,
    SMTO_BLOCK = 0x1,
    SMTO_ABORTIFHUNG = 0x2,
    SMTO_NOTIMEOUTIFNOTHUNG = 0x8,
    SMTO_ERRORONEXIT = 0x20
}

// Specific import for WM_GETTEXTLENGTH
[DllImport("user32.dll", EntryPoint = "SendMessageTimeout", CharSet = CharSet.Auto)]
internal static extern int SendMessageTimeout(
    IntPtr hwnd,
    uint Msg,              // Use WM_GETTEXTLENGTH
    int wParam,
    int lParam,
    SendMessageTimeoutFlags flags,
    uint uTimeout,
    out int lpdwResult);

// Specific import for WM_GETTEXT
[DllImport("user32.dll", EntryPoint = "SendMessageTimeout", SetLastError = true, CharSet = CharSet.Auto)]
internal static extern uint SendMessageTimeoutText(
    IntPtr hWnd,
    uint Msg,              // Use WM_GETTEXT
    int countOfChars,
    StringBuilder text,
    SendMessageTimeoutFlags flags,
    uint uTImeoutj,
    out IntPtr result);

[DllImport("user32")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool EnumChildWindows(IntPtr window, EnumWindowProc callback, IntPtr i);

// callback to enumerate child windows
private delegate bool EnumWindowProc(IntPtr hwnd, IntPtr parameter);

private static bool EnumChildWindowsCallback(IntPtr handle, IntPtr pointer)
{
    // this method will be called foreach child window
    // create a GCHandle from pointer
    var gcHandle = GCHandle.FromIntPtr(pointer);

    // cast pointer as list
    var list = gcHandle.Target as List<IntPtr>;

    if (list == null)
        throw new InvalidCastException("Invalid cast of GCHandle as List<IntPtr>");

    // Adds the handle to the list.
    list.Add(handle);

    return true;
}

private static IEnumerable<IntPtr> GetChildWindows(IntPtr parent)
{
    // Create list to store child window handles.
    var result = new List<IntPtr>();

    // Allocate list handle to pass to EnumChildWindows.
    var listHandle = GCHandle.Alloc(result);

    try
    {
        // enumerates though the children
        EnumChildWindows(parent, EnumChildWindowsCallback, GCHandle.ToIntPtr(listHandle));
    }
    finally
    {
        // free unmanaged list handle
        if (listHandle.IsAllocated)
            listHandle.Free();
    }

    return result;
}

internal static string GetText(IntPtr hwnd)
{
    const uint WM_GETTEXTLENGTH = 0x000E;
    const uint WM_GETTEXT = 0x000D;
    int length;
    IntPtr p;

    var result = SendMessageTimeout(hwnd, WM_GETTEXTLENGTH, 0, 0, SendMessageTimeoutFlags.SMTO_ABORTIFHUNG, 5, out length);

    if (result != 1 || length <= 0)
        return string.Empty;

    var sb = new StringBuilder(length + 1);

    return SendMessageTimeoutText(hwnd, WM_GETTEXT, sb.Capacity, sb, SendMessageTimeoutFlags.SMTO_ABORTIFHUNG, 5, out p) != 0 ?
            sb.ToString() : 
            string.Empty;
}

public static void Main(string[] args)
{
    var p = Process.GetProcessesByName("WindowsFormsApplication1").First();            

    Console.WriteLine(GetText(p.MainWindowHandle));    // main window handle of form, returns "Form1"
    Console.WriteLine(GetText(new IntPtr(0x70BA0)));   // actual textbox handle, used Winspector, returns "quertz"

    // iterate through dynamic handles of children
    foreach (var hwnd in GetChildWindows(p.MainWindowHandle))
        Console.WriteLine($"{hwnd}:{GetText(hwnd)}");

    Console.ReadLine();
}     

答案 1 :(得分:0)

要保存大量代码,可以使用Autoit库。

安装名为__qualname__的nuget软件包

x