有没有办法在另一个应用程序的应用程序的文本框中编写/读取文本。 我能做的是我可以使用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>();
}
}
答案 0 :(得分:2)
使用GetWindowText
方法阅读文字,使用SetWindowText
设置文字。
但是,如果你控制两个应用程序,你真的应该考虑使用旧学校命名管道,共享内存或最新的WCF来实现某种进程间通信。
答案 1 :(得分:1)
您应该专注于进程间通信以实现您的目标。作为同一台机器上的两个进程,我建议您创建一个named pipe.