Как я могу получить функциональность, подобную Шпиону ++ в моем приложении C#?

Я интересуюсь работой над плагином для Keepass, менеджера паролей с открытым исходным кодом. Прямо сейчас Keepass в настоящее время обнаруживает то, что пароль к скопировать/вставить для Вас основывал прочь заголовка окна. Это препятствует тому, чтобы Keepass обнаружил текущий пароль, в котором Вы нуждаетесь для приложений, которые активно не обновляют их заголовок окна на основе текущего сайта (Chrome, например).

Как я могу обойти через другое окно процессов элементы (кнопки, маркировки, текстовое поле) подобный тому, как Шпион ++ работает? При выполнении Шпиона ++, можно нависнуть над другими окнами программ и получить все виды информации о различных свойствах относительно различных средств управления (маркировки, текстовые поля, и т.д.). Идеально, я хотел бы, чтобы мой плагин Keepass улучшил текущее обнаружение окна путем обхода через элементы активного окна, чтобы найти учетную запись соответствия к скопировать/вставить паролю.

Как я могу обойти другие элементы окна процессов и быть в состоянии получить маркировку и значения текстового поля с помощью C#?

10
задан 28 December 2009 в 21:45
поделиться

4 ответа

Я тут отвечаю на подобные вопросы: Как я могу определить, есть ли у нити оконные ручки? . Как и говорится, основная идея заключается в том, чтобы перечислить через окна процесса и их дочерние окна, используя EnumWindows и EnumChildWindows API вызовы, чтобы получить оконные дескрипторы, а затем вызвать GetWindowText или SendDlgItemMessage с помощью WM_GETTEXT, чтобы получить текст окна. Я модифицировал код, чтобы сделать пример, который должен делать то, что нужно (извините, он немного длинный :). Он итератует через процессы и их окна и сбрасывает текст окна в консоль.

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

надеемся, что это поможет, уважаемый

.
25
ответ дан 3 December 2019 в 14:24
поделиться

Вы можете использовать EnumWindows, чтобы найти каждое окно Chrome верхнего уровня, а затем вызвать EnumChildWindows рекурсивно (см. комментарий Jeroen Wiert Pluimers), чтобы получить каждого дочернего элемента главного окна. В качестве альтернативы, как только у вас будет главное окно Chrome, вы можете использовать GetWindow для ручной навигации по дереву, так как вы, вероятно, знаете, что вы ищете (3-я дочерняя коллекция или что-то подобное).

Как только вы найдёте своё окно, вы можете использовать SendMessage с параметром WM_GETTEXT для считывания метки окна.

.
3
ответ дан 3 December 2019 в 14:24
поделиться

Посмотрите на эту статью здесь , которая содержит информацию об управляемом шпионе и о том, почему автор написал этот инструмент.

.
3
ответ дан 3 December 2019 в 14:24
поделиться

Для функциональности наведения на окно. Вам необходимо SetCapture(), чтобы получить сообщения мыши, которые находятся за пределами вашего окна. Затем используйте WindowFromPoint() для преобразования положения мыши в окно. Сначала необходимо преобразовать положение мыши из координат клиента в координаты окна.

Если вы попробуете вызвать SetCapture() где угодно, но только не при щелчке мышью, то, скорее всего, вас проигнорируют. По этой причине Spy++ заставляет вас нажать на иконку и перетащить ее в окно, на которое вы хотите навести.

.
1
ответ дан 3 December 2019 в 14:24
поделиться
Другие вопросы по тегам:

Похожие вопросы: