c# - 从另一个应用程序在一个应用程序的文本框中写入/读取文本

标签 c# winapi pinvoke

有没有办法从另一个应用程序的应用程序的文本框中写入/读取文本。 我能做的是我可以使用 win32 api 获取该文本框的句柄。但不知道如何在文本框中写入文字。 我的代码如下。 请参阅WriteTextUsingHandle方法

public class WriteText
{        
    public delegate bool EnumWindowProc(IntPtr hWnd, IntPtr parameter);

    [DllImport("user32.dll", SetLastError = true)]
    static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);

    [DllImport("user32.dll", SetLastError = true)]
    public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className, IntPtr windowTitle);

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

    [DllImport("user32.dll")]
    static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, long wParam, [MarshalAs(UnmanagedType.LPStr)] StringBuilder lParam);

    [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
    public static extern IntPtr GetParent(IntPtr hWnd);

    [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
    static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);

    public static void WriteTextUsingHandle(String text)
    {
        Process reqProcess = null;
        foreach (Process aProcess in Process.GetProcessesByName("any app"))
        {
            reqProcess = aProcess;
            break;
        }

        if (reqProcess == null) return;

        HanldesInfo dialogClasses = WriteText.GetChildWindows(reqProcess.MainWindowHandle, true, "#32770", String.Empty);
        HanldesInfo editBoxHandle = WriteText.GetChildWindows(dialogClasses.ChildHandles[1], true, "Edit", String.Empty);

        //now i want to write/Read the text using editBoxHandle. But how ?
    }

    /// <summary>
    /// Returns a list of child windows
    /// </summary>
    /// <param name="parent">Parent of the windows to return</param>
    /// <returns>List of child windows</returns>
    private static HanldesInfo GetChildWindows(IntPtr parent, bool onlyImmediateChilds, String className, String text)
    {
        HanldesInfo result = new HanldesInfo(parent, onlyImmediateChilds, className, text);
        GCHandle listHandle = GCHandle.Alloc(result);
        try
        {
            EnumChildWindows(parent, WriteText.EnumWindowAllChildCallBackMethod, GCHandle.ToIntPtr(listHandle));
        }
        finally
        {
            if (listHandle.IsAllocated) { listHandle.Free(); }
        }
        return result;
    }

    /// <summary>
    /// Callback method to be used when enumerating windows.
    /// </summary>
    /// <param name="handle">Handle of the next window</param>
    /// <param name="pointer">Pointer to a GCHandle that holds a reference to the list to fill</param>
    /// <returns>True to continue the enumeration, false to fail</returns>
    private static bool EnumWindowAllChildCallBackMethod(IntPtr handle, IntPtr pointer)
    {
        GCHandle gch = GCHandle.FromIntPtr(pointer);
        HanldesInfo list = gch.Target as HanldesInfo;

        if (list == null) { throw new InvalidCastException("GCHandle Target could not be cast as List<IntPtr>"); }

        if (list.OnlyImmediateChilds && list.ParentHandle != WriteText.GetParent(handle)) return true;

        if (list.ClassName.Length > 0)
        {
            StringBuilder className = new StringBuilder(100);
            WriteText.GetClassName(handle, className, className.Capacity);

            if (String.Compare(className.ToString().Trim(), list.ClassName, true) != 0) return true;
        }

        list.ChildHandles.Add(handle);

        //  if you want to cancel the operation, then return a null here
        return true;
    }
}

public class HanldesInfo
{
    public IntPtr ParentHandle { get; private set; }
    public bool OnlyImmediateChilds { get; private set; }
    public String ClassName { get; private set; }
    public String Text { get; private set; }
    public List<IntPtr> ChildHandles { get; private set; }

    internal HanldesInfo(IntPtr parentHandle, bool onlyImmediateChilds) : this(parentHandle, onlyImmediateChilds, String.Empty, String.Empty) { }
    internal HanldesInfo(IntPtr parentHandle, bool onlyImmediateChilds, String className) : this(parentHandle, onlyImmediateChilds, String.Empty, String.Empty) { }
    internal HanldesInfo(IntPtr parentHandle, bool onlyImmediateChilds, String className, String text)
    {
        this.ParentHandle = parentHandle;
        this.OnlyImmediateChilds = onlyImmediateChilds;
        this.ClassName = (className ?? String.Empty).Trim();
        this.Text = (text ?? String.Empty).Trim();
        this.ChildHandles = new List<IntPtr>();
    }
}

最佳答案

使用GetWindowText读取文本的方法和 SetWindowText设置文本。

但是,如果您控制这两个应用程序,则确实应该考虑使用老式命名管道、共享内存或最新的 WCF 来实现某种进程间通信。

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

相关文章:

C# P/调用 : How to achieve double indirection for a field of a structured parameter

c# - 为什么我的数据绑定(bind) TabControl 看起来不像我的非数据绑定(bind) TabControl?

c# - 比较两个 DATE 并在 C# 中获取天数

c# - DateTime.ToBinary() 和 DateTime.ToFileTime() 有何不同?

c++ - 将监视器显示上的大数字与 MONITORINFOEX 中的 szDevice 进行匹配

c# - C++ 到 C# : PInvoke\Marshaling a callback with a complex type

c# - URI 中指定的查询使用 Web API OData 无效

c# - .net WPF 应用程序在启动时崩溃(错误报告窗口)

windows - FindWindow 收到的句柄是否需要释放?

Linux。哪个dll包含execv?