我有兴趣为开源密码管理员
Keepass开发一个插件.现在,Keepass目前根据窗口标题检测到什么密码复制/粘贴.这样可以防止Keepass从当前网站(例如Chrome)中不会主动更新其窗口标题的应用程序检测到您需要的当前密码.
我如何通过另一个进程窗口元素(按钮,标签,文本框)与Spy的工作方式类似?当您运行间谍时,您可以将鼠标悬停在其他程序窗口上,并获取有关各种控件(标签,文本框等)的各种属性的各种信息.理想情况下,我想让我的Keepass插件通过浏览活动窗口的元素来增强当前的窗口检测,以找到匹配的帐户来复制/粘贴密码.
如何使用其他进程窗口元素,并可以使用C#检索标签和文本框值?
解决方法
我正在回答类似的问题:
How can I detect if a thread has windows handles?.像它所说,主要的想法是通过进程窗口和他们的子窗口枚举使用
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<IntPtr> _results = new List<IntPtr>(); 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; }
希望这有帮助,问候