如何在我的C#应用​​程序中获得与Spy ++类似的function?

我对开源密码管理器Keepass的插件感兴趣。 目前, Keepass目前根据窗口标题检测要为您复制/粘贴的密码。 这可以防止Keepass检测到根据当前站点(例如Chrome)未主动更新其窗口标题的应用所需的当前密码。

如何浏览与Spy ++工作方式类似的其他进程窗口元素(按钮,标签,文本框)? 当您运行Spy ++时,您可以将鼠标hover在其他程序窗口上,并获取有关各种控件(标签,文本框等)的各种属性的各种信息。 理想情况下,我希望我的Keepass插件通过遍历活动窗口的元素来增强当前窗口检测,以便找到匹配的帐户来复制/粘贴密码。

如何使用C#处理其他进程窗口元素并能够检索标签和文本框值?

我在这里回答类似这样的问题: 如何检测线程是否有窗口句柄? 。 就像它说的那样,主要的想法是使用EnumWindows和EnumChildWindows API调用来枚举进程窗口及其子窗口以获取窗口句柄,然后使用WM_GETTEXT调用GetWindowText或SendDlgItemMessage来获取窗口文本。 我修改了代码来做一个应该做你需要的例子(对不起,它有点长:)。 它遍历进程及其窗口并将窗口文本转储到控制台中。

static void Main(string[] args) { foreach (Process procesInfo in Process.GetProcesses()) { Console.WriteLine("process {0} {1:x}", procesInfo.ProcessName, procesInfo.Id); foreach (ProcessThread threadInfo in procesInfo.Threads) { // uncomment to dump thread handles //Console.WriteLine("\tthread {0:x}", threadInfo.Id); IntPtr[] windows = GetWindowHandlesForThread(threadInfo.Id); if (windows != null && windows.Length > 0) foreach (IntPtr hWnd in windows) Console.WriteLine("\twindow {0:x} text:{1} caption:{2}", hWnd.ToInt32(), GetText(hWnd), GetEditText(hWnd)); } } Console.ReadLine(); } private static IntPtr[] GetWindowHandlesForThread(int threadHandle) { _results.Clear(); EnumWindows(WindowEnum, threadHandle); return _results.ToArray(); } // enum windows private delegate int EnumWindowsProc(IntPtr hwnd, int lParam); [DllImport("user32.Dll")] private static extern int EnumWindows(EnumWindowsProc x, int y); [DllImport("user32")] private static extern bool EnumChildWindows(IntPtr window, EnumWindowsProc callback, int lParam); [DllImport("user32.dll")] public static extern int GetWindowThreadProcessId(IntPtr handle, out int processId); private static List _results = new List(); private static int WindowEnum(IntPtr hWnd, int lParam) { int processID = 0; int threadID = GetWindowThreadProcessId(hWnd, out processID); if (threadID == lParam) { _results.Add(hWnd); EnumChildWindows(hWnd, WindowEnum, threadID); } return 1; } // get window text [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount); [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] static extern int GetWindowTextLength(IntPtr hWnd); private static string GetText(IntPtr hWnd) { int length = GetWindowTextLength(hWnd); StringBuilder sb = new StringBuilder(length + 1); GetWindowText(hWnd, sb, sb.Capacity); return sb.ToString(); } // get richedit text public const int GWL_ID = -12; public const int WM_GETTEXT = 0x000D; [DllImport("User32.dll")] public static extern int GetWindowLong(IntPtr hWnd, int index); [DllImport("User32.dll")] public static extern IntPtr SendDlgItemMessage(IntPtr hWnd, int IDDlgItem, int uMsg, int nMaxCount, StringBuilder lpString); [DllImport("User32.dll")] public static extern IntPtr GetParent(IntPtr hWnd); private static StringBuilder GetEditText(IntPtr hWnd) { Int32 dwID = GetWindowLong(hWnd, GWL_ID); IntPtr hWndParent = GetParent(hWnd); StringBuilder title = new StringBuilder(128); SendDlgItemMessage(hWndParent, dwID, WM_GETTEXT, 128, title); return title; } 

希望这会有所帮助,问候

看看这篇文章,其中包含有关Managed Spy的信息以及作者编写该工具的原因。

您可以使用EnumWindows查找每个顶级Chrome窗口,然后递归调用EnumChildWindows (请参阅Jeroen Wiert Pluimers的评论)以获取主窗口的每个子项。 或者,一旦您拥有主Chrome窗口,您就可以使用GetWindow手动导航树,因为您可能知道您正在寻找什么(第三个孩子的儿童集合或类似的东西)。

找到窗口后,可以使用带有WM_GETTEXT参数的SendMessage来读取窗口的标签。

用于指向窗口的function。 您需要SetCapture()以便获得窗口之外的鼠标消息。 然后使用WindowFromPoint()将鼠标位置转换为Window。 您需要首先将moust位置从客户端坐标转换为窗口坐标。

如果您尝试在鼠标单击消息的任何地方调用SetCapture() ,您可能会被忽略。 这就是Spy ++让你点击一个Icon并将其拖放到你想指向的窗口上的原因。

你可以使用HWndSpy。 源代码在这里 。

在此处输入图像描述