簡體   English   中英

如何在我的C#應用​​程序中獲得與Spy ++類似的功能?

[英]How can I get functionality similar to Spy++ in my C# app?

我有興趣為開源密碼管理器Keepass開發一個插件。 目前, Keepass目前根據窗口標題檢測要為您復制/粘貼的密碼。 這可以防止Keepass檢測到根據當前站點(例如Chrome)未主動更新其窗口標題的應用所需的當前密碼。

如何通過類似於Spy ++工作方式的其他進程窗口元素(按鈕,標簽,文本框)? 當您運行Spy ++時,您可以將鼠標懸停在其他程序窗口上,並獲取有關各種控件(標簽,文本框等)的各種屬性的各種信息。 理想情況下,我希望我的Keepass插件通過遍歷活動窗口的元素來增強當前窗口檢測,以便找到匹配的帳戶來復制/粘貼密碼。

如何使用C#處理其他進程窗口元素並能夠檢索標簽和文本框值?

我在這里回答類似這樣的問題: 如何檢測線程是否有窗口句柄? 就像它說的那樣,主要的想法是使用EnumWindowsEnumChildWindows 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;
}

希望這有幫助,問候

您可以使用EnumWindows查找每個頂級Chrome窗口,然后遞歸調用EnumChildWindows (請參閱Jeroen Wiert Pluimers的評論)以獲取主窗口中的每個孩子。 或者,一旦您擁有主Chrome窗口,您就可以使用GetWindow手動導航樹,因為您可能知道您正在尋找什么(第三個孩子的兒童集合或類似的東西)。

找到窗口后,可以使用帶有WM_GETTEXT參數的SendMessage來讀取窗口的標簽。

看看這篇文章其中包含有關Managed Spy的信息以及作者編寫該工具的原因。

您可以使用HWndSpy。 源代碼在這里

在此輸入圖像描述

用於指向窗口的功能。 您需要SetCapture()以便獲得窗口外的鼠標消息。 然后使用WindowFromPoint()將鼠標位置轉換為Window。 您需要首先將moust位置從客戶端坐標轉換為窗口坐標。

如果您嘗試在鼠標單擊消息的任何地方調用SetCapture() ,您可能會被忽略。 這就是Spy ++讓你點擊一個Icon並將其拖放到你想指向的窗口上的原因。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM