PInvoke错误调用外部SetWindowsHookEx和GetModuleHandle

时间:2011-10-14 23:10:06

标签: c# hook pinvoke setwindowshookex

我正在尝试将程序中的Windows挂钩设置为外部EXE。这将用于监视窗口的大小调整/最小化,因此我可以类似地调整我的程序,停靠到窗口。

如何绕过下面的错误代码 1428 126

使用null hMod调用 SetWindowsHookEx 时,我收到此错误 1428 。如果传递当前模块(而不是IntPtr.Zero),我似乎得到了相同的错误,它似乎正确,如下:

IntPtr module = PInvoke.GetModuleHandle(null);
[...]
SetWindowsHookEx(...,...,module,...);
int error = PInvoke.GetLastError();

1428 = 无法在没有模块句柄的情况下设置非本地挂钩

我还尝试使用 GetModuleHandle 抓取我作为模块挂钩的外部程序:

IntPtr module = PInvoke.GetModuleHandle("communicator.exe");
int error = PInvoke.GetLastError();

错误则设置为:

126 = 找不到指定的模块。

我正在使用以下PInvoke语句:

[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr GetModuleHandle(string lpModuleName);

[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr SetWindowsHookEx(HookType hookType, HookProc lpfn, IntPtr hMod, uint dwThreadId);

这是遇到问题的程序:

public void Install(IntPtr hWnd)
    {
        uint threadId;
        uint processId;

        if (hWnd == IntPtr.Zero)
        {
            threadId = (uint)AppDomain.GetCurrentThreadId();
            throw new Exception("Lync thread not found!");
        }
        else
        {
            threadId = PInvoke.GetWindowThreadProcessId(hWnd, out processId);
        }

        //IntPtr module = PInvoke.GetModuleHandle(null);
        //IntPtr module = PInvoke.GetModuleHandle(GetType().Module.FullyQualifiedName);
        IntPtr module = PInvoke.GetModuleHandle("communicator.exe");
        int error = PInvoke.GetLastError();

        m_hhook = PInvoke.SetWindowsHookEx(
            m_hookType,
            m_filterFunc,
            //Process.GetCurrentProcess().Handle,
            //threadId);
            //IntPtr.Zero,
            //module,
            //Marshal.GetHINSTANCE(
            //                                System.Reflection.Assembly.GetExecutingAssembly().GetModules()[0]
            //                        ).ToInt32()
            module,
            threadId);

        //IntPtr hinst = Marshal.GetHINSTANCE(Process.GetCurrentProcess().Handle);

        // http://msdn.microsoft.com/en-us/library/ms681385
        // ERROR_HOOK_NEEDS_HMOD - 1428 = Cannot set nonlocal hook without a module handle
        error = PInvoke.GetLastError();
    }

2 个答案:

答案 0 :(得分:4)

您无法将GetModuleHandle用于外部流程。它必须是已加载到当前进程中的模块。

答案 1 :(得分:1)

我遇到了同样的问题:126 =找不到指定的模块。 我在我的应用程序中添加了缺少的消息循环,它又开始工作了。

我正在使用这样的Hook func:

 hKeyboardHook = SetWindowsHookEx(
                    WH_KEYBOARD_LL,
                    KeyboardHookProcedure,
                    Marshal.GetHINSTANCE(typeof(your_class_type).Module),
                    0);

我在主要功能

的末尾添加了Application.Run()