visual studio spyxx que portable c# winapi spy++

c# - spyxx - spy++ visual studio 2017



¿Cómo puedo obtener una funcionalidad similar a la de Spy++ en mi aplicación C#? (5)

Para la funcionalidad de señalar a una ventana. Necesita SetCapture() para que pueda obtener los mensajes del mouse que están fuera de su ventana. Luego use WindowFromPoint() para convertir la posición de un mouse en una ventana. Primero tendrá que convertir la posición de la palanca de las coordenadas del cliente a las coordenadas de la ventana.

Si intentas una llamada SetCapture() cualquier lugar, pero con un clic del mouse, probablemente seas ignorado. Esta es la razón por la que Spy ++ hace que haga clic en un icono y lo arrastre y lo suelte en la ventana a la que desea apuntar.

Estoy interesado en trabajar en un complemento para Keepass , el administrador de contraseñas de código abierto. En este momento, Keepass actualmente detecta qué contraseña copiar / pegar basándose en el título de la ventana. Esto evita que Keepass detecte la contraseña actual que necesita para las aplicaciones que no actualizan activamente el título de su ventana en función del sitio actual (por ejemplo, Chrome).

¿Cómo puedo recorrer otros elementos de la ventana de procesos (botones, etiquetas, cuadros de texto) de forma similar a cómo funciona Spy ++? Cuando ejecuta Spy ++, puede pasar el puntero del mouse sobre otras ventanas de programas y obtener todo tipo de información sobre varias propiedades relacionadas con varios controles (etiquetas, cuadros de texto, etc.). Idealmente, me gustaría que mi complemento Keepass mejore la detección de ventanas actual al recorrer los elementos de la ventana activa en un esfuerzo por encontrar una cuenta coincidente para copiar / pegar la contraseña.

¿Cómo puedo recorrer otros elementos de la ventana de procesos y poder recuperar valores de etiquetas y cuadros de texto usando C #?


Echa un vistazo a este artículo que contiene información sobre Managed Spy y por qué el autor escribió la herramienta.


Puede usar EnumWindows para buscar todas las ventanas de Chrome de nivel superior y luego llamar a EnumChildWindows recursivamente (consulte el comentario de Jeroen Wiert Pluimers) para obtener todos los elementos secundarios de la ventana principal. Alternativamente, una vez que tenga la ventana principal de Chrome, puede usar GetWindow para navegar manualmente por el árbol ya que probablemente sepa lo que está buscando (colección de niños del 3er niño o algo similar).

Una vez que encuentre su ventana, puede usar SendMessage con un parámetro WM_GETTEXT para leer la etiqueta de la ventana.


Puedes usar HWndSpy. El código fuente está aquí .


He estado respondiendo preguntas similares a esta aquí: ¿Cómo puedo detectar si un hilo tiene identificadores de ventanas? . Como dice, la idea principal es enumerar a través de las ventanas de procesos y sus ventanas secundarias las llamadas EnumWindows y EnumChildWindows API para obtener identificadores de ventana y luego llamar a GetWindowText o SendDlgItemMessage con WM_GETTEXT para obtener texto de ventana. He modificado el código para hacer un ejemplo que debería estar haciendo lo que necesita (lo siento, es un poco largo :). Se repite a través de los procesos y sus ventanas y vuelca el texto de la ventana en la consola.

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; }

Espero que esto ayude, saludos