如何在C#应用程序中获得与Spy类似的功能?

前端之家收集整理的这篇文章主要介绍了如何在C#应用程序中获得与Spy类似的功能?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有兴趣为开源密码管理员 Keepass开发一个插件.现在,Keepass目前根据窗口标题检测到什么密码复制/粘贴.这样可以防止Keepass从当前网站(例如Chrome)中不会主动更新其窗口标题的应用程序检测到您需要的当前密码.

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

如何使用其他进程窗口元素,并可以使用C#检索标签和文本框值?

解决方法

我正在回答类似的问题: How can I detect if a thread has windows handles?.像它所说,主要的想法是通过进程窗口和他们的子窗口枚举使用 EnumWindowsEnumChildWindows API调用获取窗口句柄,然后使用WM_GETTEXT调用GetWindowText或SendDlgItemMessage来获取窗口文字.我修改代码,做出一个应该做你所需要的例子(对不起,有点长:) :)它遍历进程和他们的窗口并将窗口文本转储到控制台中.
  1. static void Main(string[] args)
  2. {
  3. foreach (Process procesInfo in Process.GetProcesses())
  4. {
  5. Console.WriteLine("process {0} {1:x}",procesInfo.ProcessName,procesInfo.Id);
  6. foreach (ProcessThread threadInfo in procesInfo.Threads)
  7. {
  8. // uncomment to dump thread handles
  9. //Console.WriteLine("\tthread {0:x}",threadInfo.Id);
  10. IntPtr[] windows = GetWindowHandlesForThread(threadInfo.Id);
  11. if (windows != null && windows.Length > 0)
  12. foreach (IntPtr hWnd in windows)
  13. Console.WriteLine("\twindow {0:x} text:{1} caption:{2}",hWnd.ToInt32(),GetText(hWnd),GetEditText(hWnd));
  14. }
  15. }
  16. Console.ReadLine();
  17. }
  18.  
  19. private static IntPtr[] GetWindowHandlesForThread(int threadHandle)
  20. {
  21. _results.Clear();
  22. EnumWindows(WindowEnum,threadHandle);
  23. return _results.ToArray();
  24. }
  25.  
  26. // enum windows
  27.  
  28. private delegate int EnumWindowsProc(IntPtr hwnd,int lParam);
  29.  
  30. [DllImport("user32.Dll")]
  31. private static extern int EnumWindows(EnumWindowsProc x,int y);
  32. [DllImport("user32")]
  33. private static extern bool EnumChildWindows(IntPtr window,EnumWindowsProc callback,int lParam);
  34. [DllImport("user32.dll")]
  35. public static extern int GetWindowThreadProcessId(IntPtr handle,out int processId);
  36.  
  37. private static List<IntPtr> _results = new List<IntPtr>();
  38.  
  39. private static int WindowEnum(IntPtr hWnd,int lParam)
  40. {
  41. int processID = 0;
  42. int threadID = GetWindowThreadProcessId(hWnd,out processID);
  43. if (threadID == lParam)
  44. {
  45. _results.Add(hWnd);
  46. EnumChildWindows(hWnd,WindowEnum,threadID);
  47. }
  48. return 1;
  49. }
  50.  
  51. // get window text
  52.  
  53. [DllImport("user32.dll",CharSet = CharSet.Auto,SetLastError = true)]
  54. static extern int GetWindowText(IntPtr hWnd,StringBuilder lpString,int nMaxCount);
  55. [DllImport("user32.dll",SetLastError = true,CharSet = CharSet.Auto)]
  56. static extern int GetWindowTextLength(IntPtr hWnd);
  57.  
  58. private static string GetText(IntPtr hWnd)
  59. {
  60. int length = GetWindowTextLength(hWnd);
  61. StringBuilder sb = new StringBuilder(length + 1);
  62. GetWindowText(hWnd,sb,sb.Capacity);
  63. return sb.ToString();
  64. }
  65.  
  66. // get richedit text
  67.  
  68. public const int GWL_ID = -12;
  69. public const int WM_GETTEXT = 0x000D;
  70.  
  71. [DllImport("User32.dll")]
  72. public static extern int GetWindowLong(IntPtr hWnd,int index);
  73. [DllImport("User32.dll")]
  74. public static extern IntPtr SendDlgItemMessage(IntPtr hWnd,int IDDlgItem,int uMsg,int nMaxCount,StringBuilder lpString);
  75. [DllImport("User32.dll")]
  76. public static extern IntPtr GetParent(IntPtr hWnd);
  77.  
  78. private static StringBuilder GetEditText(IntPtr hWnd)
  79. {
  80. Int32 dwID = GetWindowLong(hWnd,GWL_ID);
  81. IntPtr hWndParent = GetParent(hWnd);
  82. StringBuilder title = new StringBuilder(128);
  83. SendDlgItemMessage(hWndParent,dwID,WM_GETTEXT,128,title);
  84. return title;
  85. }

希望这有帮助,问候

猜你在找的C#相关文章