即使应用程序未对焦,我也试图设置一个低级别的Windows键盘钩子以抓住三个键。为此,我将SetWindowsHookEx称为
// Create an instance of HookProc.
KeyboardHookProcedure = new HookProc(KeyboardHookProc);
//install hook
hKeyboardHook = SetWindowsHookEx(
WH_KEYBOARD_LL,
KeyboardHookProcedure,
Marshal.GetHINSTANCE(
Assembly.GetExecutingAssembly().GetModules()[0]),
0);
//If SetWindowsHookEx fails.
if (hKeyboardHook == 0)
{
//Returns the error code returned by the last unmanaged function called using platform invoke that has the DllImportAttribute.SetLastError flag set.
int errorCode = Marshal.GetLastWin32Error();
//do cleanup
Stop(false, true, false);
//Initializes and throws a new instance of the Win32Exception class with the specified error.
throw new Win32Exception(errorCode);
}
这曾经使用.NET Framework 3.5在32位和64位计算机上运行,但在升级到.NET Framework 4.0后停止在32位计算机上运行。
有谁知道如何解决这个问题,以便我可以使用4.0 Framework并在32位和64位计算机上运行?
答案 0 :(得分:23)
像这样导入dll:
[DllImport("kernel32.dll")]
public static extern IntPtr GetModuleHandle(string name);
然后使用
GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName)
替换
Marshal.GetHINSTANCE(
Assembly.GetExecutingAssembly().GetModules()[0]
答案 1 :(得分:2)
hMod [in]
的 HINSTANCE 强>
DLL的句柄,包含lpfn参数指向的钩子过程。如果dwThreadId参数指定当前进程创建的线程,并且钩子过程位于与当前进程关联的代码内,则必须将hMod参数设置为NULL。
所以你应该在IntPtr.Zero中传递NULL
//install hook
hKeyboardHook = SetWindowsHookEx(
WH_KEYBOARD_LL,
KeyboardHookProcedure,
IntPtr.Zero,
0);
答案 2 :(得分:1)
通过单独定位每个平台解决了这个问题。配置VS以编译Win32和Win64版本,并在x86和x64机器上部署相应的二进制文件。
Win32或x86在32位和64位计算机上运行。
答案 3 :(得分:0)
任何模块句柄都可以,因为它实际上并没有被使用 低级钩子,不需要注入DLL来使它们工作。一些 因为不再使用CLR,因此.NET 4需要注意选择一个 用于纯托管程序集的fakes模块句柄。一个好用的是 你可以通过pinvoking LoadLibrary(“user32.dll”)得到的 总是已加载。您不必调用FreeLibrary()。
您需要此声明才能调用LoadLibrary:
[DllImport("kernel32", SetLastError=true, CharSet = CharSet.Auto)] private static extern IntPtr LoadLibrary(string fileName);