ang*_*son 14 64-bit 32-bit .net-4.0 .net-3.5 setwindowshookex
我在这个页面上发现了类似的问题,但我似乎无法弄清楚如何解释答案或弄清楚它们是否真的重复.
以下是我发现的可能重复项,并附有评论:
在32位计算机上编译.NET 4.0框架时,SetWindowsHookEx返回0
它似乎没有返回0我的,但我注意到崩溃时报告的句柄(32位上的.NET 4.0)与运行时报告的句柄不同(32位上的.NET 3.5),像崩溃句柄= 523727,工作句柄= 172738378.
在VS2008调试器中调用SetWindowsHookEx始终返回NULL
我可以在Visual Studio外部运行时重现我的问题
这似乎是最有希望的,除了对删除的答案的评论提到我应该使用LoadLibrary和GetProcAddress来加载.NET 4.0中的user32.dll,因为有关加载程序集的更改.但是,我很确定它是我自己无法找到的模块,但我不知道这是否适用.
Hans Passant对最后一个删除答案的评论如下:
你在使用.NET 4.0吗?它的CLR改变了程序集的加载方式,不再有LoadLibrary调用,也没有模块句柄.使用GetEntryAssembly()代替另一种修复. - 汉斯帕斯特5月5日19:43
那么,这里的字是什么?你在使用.NET 4.0吗?您是否尝试使用LoadLibrary("user32.dll")来获取可用的DLL句柄? - Hans Passant 5月6日15:43
我很确定我不需要这样做,但显然我不是百分百肯定.如果我需要更改它,我留下的问题是,为什么它适用于64位操作系统,在编译时Any CPU,但在任何配置中都不适用于32位.
如果加载.NET程序集确实发生了一些变化,那么我没有得到类库的正确句柄,我有以下问题:
背景
我在.NET 4.0中构建了一个程序,它使用带有WH_KEYBOARD_LL钩子类型的SetWindowsHookEx来捕获按键.这在我的64位Windows 7上运行良好,但在32位Windows 7上安装键盘挂钩时崩溃时出现"找不到模块".
这是我尝试过的:
我宁愿不将我的代码切换到.NET 3.5,因为我使用了一些类库来简化工作,而最新的代码只在.NET 4.0中.
如果需要,可以下载包含Visual Studio 2010项目的.ZIP文件,也可以粘贴以下两个文件.
要重新创建是否要沿着该路线前进:
然后构建并运行,测试各种配置.
using System;
using HookLib;
namespace HookTest
{
class Program
{
static void Main()
{
var hook = new Hook();
Console.Out.WriteLine("hooking");
hook.Enable();
Console.Out.WriteLine("hooked");
Console.Out.WriteLine("unhooking");
hook.Disable();
Console.Out.WriteLine("unhooked");
}
}
}
Run Code Online (Sandbox Code Playgroud)
using System;
using System.ComponentModel;
using System.Reflection;
using System.Runtime.InteropServices;
namespace HookLib
{
public class Hook
{
private IntPtr _Handle;
private HookProcDelegate _Hook;
public void Enable()
{
Module module = Assembly.GetExecutingAssembly().GetModules()[0];
if (module != null)
Console.Out.WriteLine("found module");
IntPtr moduleHandle = Marshal.GetHINSTANCE(module);
if (moduleHandle != IntPtr.Zero)
Console.Out.WriteLine("got module handle: " +
moduleHandle.ToString());
_Hook = HookProc;
_Handle = SetWindowsHookEx(WH_KEYBOARD_LL, _Hook, moduleHandle, 0);
if (_Handle == IntPtr.Zero)
throw new Win32Exception(Marshal.GetLastWin32Error());
}
public void Disable()
{
bool ok = UnhookWindowsHookEx(_Handle);
_Handle = IntPtr.Zero;
if (!ok)
throw new Win32Exception(Marshal.GetLastWin32Error());
}
private delegate int HookProcDelegate(
int code, IntPtr wParam, IntPtr lParam);
private int HookProc(int code, IntPtr wParam, IntPtr lParam)
{
return CallNextHookEx(_Handle, code, wParam, lParam);
}
private const int WH_KEYBOARD_LL = 13;
[DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr SetWindowsHookEx(
int hookType, HookProcDelegate lpfn, IntPtr hMod, uint dwThreadId);
[DllImport("user32.dll", SetLastError = true)]
private static extern bool UnhookWindowsHookEx(IntPtr hhk);
[DllImport("user32.dll", SetLastError = true)]
private static extern int CallNextHookEx(
IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);
}
}
Run Code Online (Sandbox Code Playgroud)
Han*_*ant 17
是的,我想你明白发生了什么.SetWindowsHookEx()需要一个有效的模块句柄,并对其进行验证,但在设置低级别挂钩时它实际上并不使用它.你只需要一个有效的句柄,哪个特定的句子无关紧要.调用LoadLibrary("user32.dll")是获取句柄的好方法,因为P/Invoke其方法,所以始终会加载DLL.它始终由CLR引导程序(mscoree.dll)加载.不要打扰FreeLibrary(),它没有任何区别.
更高版本的Windows不再执行此检查.不完全确定何时开始,我认为在Windows 7 SP1附近.可能意味着有用,但调用"在我的机器上工作,而不是客户的"故障情形.
| 归档时间: |
|
| 查看次数: |
5092 次 |
| 最近记录: |