加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-15 17:43:45 所属栏目:百科 来源:网络整理
导读:我有兴趣为开源密码管理员 Keepass开发一个插件.现在,Keepass目前根据窗口标题检测到什么密码复制/粘贴.这样可以防止Keepass从当前网站(例如Chrome)中不会主动更新其窗口标题的应用程序检测到您需要的当前密码. 我如何通过另一个进程窗口元素(按钮,标签,文本
我有兴趣为开源密码管理员 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;
}

希望这有帮助,问候

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读