我有一个桌面应用程序安装在我的计算机上。当我启动程序时,会弹出某种窗口,就像这个例子:
。
因此,我想用C#编写一个应用程序,可以找到这个窗口并从中获取一些数据。
我应该使用哪些工具?我希望选择最简单的方法。
我需要捕获图像、文本框中的文本,并通过文本查找控件并单击它们。
![enter image description here](https://istack.dev59.com/OOQL9.webp)
因此,我想用C#编写一个应用程序,可以找到这个窗口并从中获取一些数据。
我应该使用哪些工具?我希望选择最简单的方法。
我需要捕获图像、文本框中的文本,并通过文本查找控件并单击它们。
https://dev59.com/rHE85IYBdhLWcg3w8IbK#2584672
对于每个句柄,获取文本和位置信息,使用位置信息可以在该位置上截取桌面屏幕以获取图像。据我所知,没有其他方法可以从运行应用程序的窗口中获取图像。https://dev59.com/cWkv5IYBdhLWcg3wxjvQ#10355905
我组织了一个快速班级来收集那些用于处理的数据。 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);
}
}
你想捕获什么类型的数据?
你可以尝试监听 Windows 消息或读取内存。
根据您未来要执行这些类型任务的数量(或者这一个任务的重要性),您可以尝试投资一些类似Ranorex Spy这样的工具(Ranorex Studio也很不错)。
除了注入您想要检查的应用程序之外,没有其他方法。这就是UISpy实际运行的方式。这也是为什么应该使用管理员凭据运行UISpy的原因。