我的计算机上安装了桌面应用程序。当我启动一个程序时,某种窗口会被打开。让我们说,像这样(只是例子):
所以,我想用C#编写一个应用程序来找到这个窗口并从中捕获一些数据。
我应该看什么工具?我想走的是阻力最小的道路。
我需要从文本框中捕获图像,文本,还可以通过文本查找控件并单击它们。
答案 0 :(得分:6)
我建议您使用这个很酷但鲜为人知的UI Automation API来完成这项工作。
为此,首先要测试的是启动相关的UISpy工具。它将在屏幕上显示所有可访问窗口的树。它还可以运行一些操作,例如按下菜单,选择项目等。这是使用所谓的UI Automation Control Patterns,它提供了一种分类和公开控件功能的方法,与控件类型或外观无关。控制。
因此,如果你可以使用UI Spy自动化这个应用程序,你也可以使用.NET代码做同样的事情(UISpy本身就是使用底层API)。
这是一篇关于UI自动化编程的有趣教程文章:The Microsoft UI Automation Library
答案 1 :(得分:2)
您应该开始枚举该进程的所有窗口的句柄:
https://stackoverflow.com/a/2584672/351383
然后为每个句柄获取有关文本和位置的信息,通过位置信息,您可以在该位置截取桌面的截图以获取图像AFAIK没有其他方法可以从正在运行的应用程序的窗口获取图像。
当您获得控件的屏幕位置时,请使用下面的链接模拟鼠标左键单击,搜索某些文本的窗口,然后单击控件内的某个点,这是点击某个点的方法:
https://stackoverflow.com/a/10355905/351383
我还给快速课程收集过程中的数据:
public static class ProcessSpy
{
public static List<ProcessSpyData> GetDataForProcess(string processName)
{
var result = new List<ProcessSpyData>();
Process myProc = Process.GetProcessesByName(processName).FirstOrDefault();
if (myProc != null)
{
var myHandles = EnumerateProcessWindowHandles(myProc);
foreach (IntPtr wndHandle in myHandles)
{
result.Add(new ProcessSpyData(wndHandle));
}
}
return result;
}
delegate bool EnumThreadDelegate(IntPtr hWnd, IntPtr lParam);
[DllImport("user32.dll")]
static extern bool EnumThreadWindows(int dwThreadId, EnumThreadDelegate lpfn, IntPtr lParam);
static IEnumerable<IntPtr> EnumerateProcessWindowHandles(Process prc)
{
var handles = new List<IntPtr>();
foreach (ProcessThread thread in prc.Threads)
EnumThreadWindows(thread.Id, (hWnd, lParam) => { handles.Add(hWnd); return true; }, IntPtr.Zero);
return handles;
}
}
public class ProcessSpyData
{
private const uint WM_GETTEXT = 0x000D;
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, int wParam, StringBuilder lParam);
[DllImport("user32.dll")]
private static extern bool GetClientRect(IntPtr hWnd, out RECT lpRect);
[StructLayout(LayoutKind.Sequential)]
private struct RECT
{
int left, top, right, bottom;
public Rectangle ToRectangle()
{
return new Rectangle(left, top, right - left, bottom - top);
}
}
[DllImport("user32.dll")]
static extern bool ClientToScreen(IntPtr hWnd, ref Point lpPoint);
public IntPtr WindowHandle { get; private set; }
public string WindowText { get; private set; }
public Rectangle ClientRect { get; private set; }
public Rectangle ScreenPos { get; private set; }
public ProcessSpyData(IntPtr windowHandle)
{
this.WindowHandle = windowHandle;
GetWindowText();
GetWindowSize();
}
private void GetWindowText()
{
StringBuilder message = new StringBuilder(1024);
SendMessage(this.WindowHandle, WM_GETTEXT, message.Capacity, message);
this.WindowText = message.ToString();
}
private void GetWindowSize()
{
var nativeRect = new RECT();
GetClientRect(this.WindowHandle, out nativeRect);
this.ClientRect = nativeRect.ToRectangle();
Point loc = this.ClientRect.Location;
ClientToScreen(this.WindowHandle, ref loc);
this.ScreenPos = new Rectangle(loc, this.ClientRect.Size);
}
}
这应该让你开始,但你必须知道如果应用程序使用非标准控件,那么使用此方法无法从中获取文本,对于图像,可能会在查看可执行资源时获得更好的结果
<强>更新强>
获取各种控件类型(MFC,winforms,Delphi VCL等)的控件文本将是非常艰巨的任务,但对于winforms看到优秀的Managed Windows API,他们甚至在{{3}中有某种间谍应用程序看看那个。
答案 2 :(得分:1)
您想要捕获哪种数据?
您可以尝试收听Windows消息或阅读内存。
答案 3 :(得分:0)
根据您将来要做的这些类型的任务有多少(或者这个任务有多重要),您可以尝试投资Ranorex Spy(Ranorex studio is ott)等。
答案 4 :(得分:0)
除了注入要检查的应用程序之外别无他法。这就是UISpy的实际运行方式。这也是UISpy应该与管理凭证一起运行的原因。