PInvoke errors calling external SetWindowsHookEx and GetModuleHandle

爱⌒轻易说出口 提交于 2019-12-07 23:08:13

问题


I am trying to set windows hooks in my program to an external EXE. This will be used to monitor resizing/minimizing of the window, so I can resize my program similarly, docking to the window.

How do I get around error codes 1428 and 126 below?

When calling SetWindowsHookEx with a null hMod, I was getting this error 1428. I get the same error if passing the current module (instead of IntPtr.Zero), which it seems to get correctly, as so:

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

1428 = Cannot set nonlocal hook without a module handle

I also tried to grab the external program I'm hooking as a module using GetModuleHandle:

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

But error is then set to:

126 = The specified module could not be found.

I am using the following PInvoke statements:

[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);

This is the procedure that is having the issue:

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();
    }

回答1:


You can't use GetModuleHandle for an external process. It must be a module that has been loaded into the current process.




回答2:


I had the same issue: 126 = The specified module could not be found. I added missing message loop into my app and it start working again.

I'm using Hook func like this:

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

and I added Application.Run() at tne end of the Main func



来源:https://stackoverflow.com/questions/7774509/pinvoke-errors-calling-external-setwindowshookex-and-getmodulehandle

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!