问题
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