我在我的机器上安装了桌面应用程序。当我开始一个程序时,某种窗口会打开。让我们说,这样的事情(例如只):如何捕获窗口中的数据
所以,我想C#编写的应用程序,会发现这个窗口,并从中获取一些数据。
我应该看什么工具?我想走一条阻力最小的路。
我需要捕获图像,文本框中的文本,还可以通过文本查找控件并单击它们。
我在我的机器上安装了桌面应用程序。当我开始一个程序时,某种窗口会打开。让我们说,这样的事情(例如只):如何捕获窗口中的数据
所以,我想C#编写的应用程序,会发现这个窗口,并从中获取一些数据。
我应该看什么工具?我想走一条阻力最小的路。
我需要捕获图像,文本框中的文本,还可以通过文本查找控件并单击它们。
你试图捕获什么样的数据?
您可以尝试收听Windows消息或阅读内存。
你应该开始枚举所有窗口的句柄这个过程:
https://stackoverflow.com/a/2584672/351383
然后,每处理获取有关文本和位置信息,与位置信息来源,你可以采取的桌面截图上那个位置获得图像AFAIK没有其他方式从正在运行的应用程序窗口获取图像。
当你得到了控制的屏幕位置,然后从下面的链接使用模拟鼠标左键点击,搜索窗口的一些文字,然后点击内部控制的一些点,这里是会点击一个点的方法:
https://stackoverflow.com/a/10355905/351383
我把toghether快速类收集过程数据:
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);
}
}
这应该让你开始,但你必须要知道,如果应用程序是使用非标准控件则没有用这种方法从文本中获取文本的方式,对于图像来说,查看可执行资源可能会获得更好的结果。
UPDATE
葛亭控制文本的各种控制类型(MFC,的WinForms,德尔福VCL等)将是非常艰巨的任务,但对于的WinForms看外观极好Managed Windows API,他们甚至在某种间谍应用tools,看看那个。
谢谢你一个不错的答案。我从顶部开始......你知道什么是可以让我通过文本控制位置的函数的名称(比方说按钮)。任何内部user32.dll?我到了我的窗户。现在我需要找到控制。 – user194076
窗口是控制:)在Windows API没有控件,控件通常是从很多窗口构造的。国际海事组织几乎不可能创建通用的方法来获取控件内容,获取Winforms控件的内容请参阅http://mwinapi.sourceforge.net/,我会更新我的答案 –
根据这些类型的任务你将在未来做多少(或者这是多么重要),你可以尝试投资Ranorex Spy(Ranorex studio is ott)。
我建议你使用凉爽,但鲜为人知的UI Automation API这项工作。
为此,首先要测试的是启动关联的UISpy工具。它将在屏幕上显示所有可访问窗口的树状图。它还能够执行一些操作,如按菜单,选择项目等。这就是所谓的UI Automation Control Patterns,它提供了一种独立于控件类型或控件外观的分类和公开控件功能的方法。因此,如果您可以使用UI Spy自动执行此应用程序,那么您也可以使用.NET代码完成同样的事情(UISpy本身只是使用底层API)。
以下是有关UI自动化编程一个有趣的教程文章:The Microsoft UI Automation Library
有没有其他办法,而不是注入要检查应用程序。这是UISpy实际运行的方式。这也是为什么UISpy应该使用管理凭证运行的原因。
TExtboxes \ pictures。另外我需要点击一个按钮。我应该如何听听Windows消息? – user194076
看看这篇文章:http://stackoverflow.com/questions/9665579/setting-up-hook-on-windows-messages并尝试玩间谍++(http://technet.microsoft.com/en- us/library/dd460725.aspx) – animaonline