SetWindowsHookEx在运行时在C#应用程序中失败

时间:2013-04-18 16:41:30

标签: c# .net winapi hook setwindowshookex

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

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

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

1 个答案:

答案 0 :(得分:0)

只能从托管.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事件是您要监控的事件。