【问题标题】:SetWindowHookEx fails at runtime in C# applicationSetWindowHookEx 在 C# 应用程序运行时失败
【发布时间】:2013-04-18 16:41:29
【问题描述】:

我正在构建一个应用程序使用钩子,我想启动另一个应用程序,在我构建我的应用程序之后,应用程序将获得另一个应用程序的自动化窗口句柄和 setwindowhook。但我做不到。请帮助我 :( 。我的英语 sr

当我得到所有应用程序时,变量窗口是 hwnd 是 windowform 正在运行

private bool AddWnd(int hwnd, int lparam)
{
    if (IsWindowVisible(hwnd))
    {
        StringBuilder sb = new StringBuilder(255);
        string className = GetClassName((IntPtr)hwnd).ToString();
        if (className.Length > 10)
        {
            string getSubStringClassName = className.Substring(0, 11);
            if (getSubStringClassName.Equals("WindowsForm") && IsWindow(hwnd)!=0)
            {
                GetWindowText(hwnd, sb, sb.Capacity);
                window = hwnd;
            }
        }
    }
    return true;
}

HookProc HookProcedure;
private const int WH_CBT = 5;

public void startHook()
{
    if (hHook == 0)
    {
        HookProcedure = new HookProc(CbtHookProc);
        int threadID = GetWindowThreadProcessId((IntPtr)window, out processHandle);
        IntPtr hMod = System.Runtime.InteropServices.Marshal.GetHINSTANCE(typeof(Form1).Module);
        hHook = SetWindowsHookEx(WH_CBT, HookProcedure, hMod, threadID);
        if (hHook == 0)
        {
            MessageBox.Show("SetWindowsHookEx Failed");
            return;
        }
    }
    else
    {
        bool ret = UnhookWindowsHookEx(hHook);
        //If the UnhookWindowsHookEx function fails.
        if (ret == false)
        {
            MessageBox.Show("UnhookWindowsHookEx Failed");
            return;
        }
        hHook = 0;
        button1.Text = "Set Windows Hook";   
    }
}

【问题讨论】:

    标签: c# .net winapi hook setwindowshookex


    【解决方案1】:

    只有两种类型的挂钩可以从托管 .NET 应用程序安装:低级键盘 (WH_KEYBOARD_LL) 和低级鼠标 (WH_MOUSE_LL) 挂钩。不同的是,这两个钩子的回调函数是由你自己的程序实现的。所有其他类型的钩子都需要在 DLL 中实现回调函数,该 DLL 可以实际注入到被钩子的进程中。这不适用于托管代码,因为托管 DLL 无法安全地注入到非托管进程中。

    因此,无论您如何修复您的 C# 代码,这都不会奏效。永远不能从 C# 应用程序或 DLL 安装基于计算机的培训挂钩 (WH_CBT)。您将需要切换到不同的语言来编写您的钩子 DLL; C 和 C++ 是常见的选择。

    或者,如果您只关心在另一个应用程序创建窗口时接收通知,您可以改用可访问性 API,它在托管应用程序中工作。开始调查SetWinEventHook function。您需要指定WINEVENT_OUTOFCONTEXT 标志以确保将通知传递到您的进程;否则需要一个可注入的 DLL,我们已经知道它是行不通的。 EVENT_OBJECT_CREATE 和/或 EVENT_OBJECT_SHOW 事件是您要监控的事件。

    【讨论】:

    • 已经有 C# 版本的无障碍 API,所以你不需要自己动手:System.Windows.Automation。它专为 WPF 应用程序使用而设计(即,进行控制的应用程序是 WPF;被控制的应用程序可以是任何东西)。
    • 请不要使用 System.Windows.Automation: stackoverflow.com/a/41768047/1204843
    猜你喜欢
    • 2013-08-02
    • 1970-01-01
    • 2021-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-26
    • 2021-12-16
    相关资源
    最近更新 更多