SetWindowsHookEx 不适用于线程 ID
您好,提前感谢任何愿意提供帮助的人。 我正在尝试设置一个 CBT windows 挂钩,当我全局设置它时它运行良好,但每当我尝试将它附加到单个线程时它就会失败。据我所知,我所做的一切都是按书本进行的: - 我从非托管 dll 中暴露了钩子过程 - 我的应用程序、dll和线程的进程都是32位的 - 我使用的线程ID是正确的(用spy++确认)
当我试图从c++代码中仅挂钩一个线程时,我设法做到了......你可以仅从非托管代码挂钩单个线程吗?
无论如何,这是我的代码:
[DllImport( "user32.dll", SetLastError = true )]
static extern IntPtr SetWindowsHookEx ( int hookType, UIntPtr lpfn, IntPtr hMod, uint dwThreadId );
[DllImport( "kernel32", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true )]
public static extern UIntPtr GetProcAddress ( IntPtr hModule, string procName );
[DllImport( "kernel32", SetLastError = true, CharSet = CharSet.Unicode )]
public static extern IntPtr LoadLibrary ( string libraryName );
const int WH_CBT = 5;
void SetHook ()
{
IntPtr dll = LoadLibrary( LIBRARY );
UIntPtr proc = GetProcAddress( dll, PROC );
uint threadId = GetAppWindowThreadId();
//assume that the threadId of the external window is correct, as I said I verified with spy++
//and assume that dll and proc both get correct values
IntPtr hookAddress = SetWindowsHookEx( WH_CBT , proc, dll, threadId );
//hookAddress is 0
}
Hello and thanks in advance to anyone thatll try to help.
I'm trying to set a CBT windows hook, which works well when Im setting it globally, but fails whenever I try to attach it to a single thread. As far as I know, Im doing everything by the book:
- I exposed the hook procedure from an unmanaged dll
- my application, the dll and the thread's process are all 32 bit
- The thread ID I use is correct (confirmed with spy++)
When I tried to hook only one thread from a c++ code, I managed to do it... can you hook a single thread only from unmanaged code?
here is my code anyway:
[DllImport( "user32.dll", SetLastError = true )]
static extern IntPtr SetWindowsHookEx ( int hookType, UIntPtr lpfn, IntPtr hMod, uint dwThreadId );
[DllImport( "kernel32", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true )]
public static extern UIntPtr GetProcAddress ( IntPtr hModule, string procName );
[DllImport( "kernel32", SetLastError = true, CharSet = CharSet.Unicode )]
public static extern IntPtr LoadLibrary ( string libraryName );
const int WH_CBT = 5;
void SetHook ()
{
IntPtr dll = LoadLibrary( LIBRARY );
UIntPtr proc = GetProcAddress( dll, PROC );
uint threadId = GetAppWindowThreadId();
//assume that the threadId of the external window is correct, as I said I verified with spy++
//and assume that dll and proc both get correct values
IntPtr hookAddress = SetWindowsHookEx( WH_CBT , proc, dll, threadId );
//hookAddress is 0
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
该声明是错误的。最后一个参数 (dwThreadId) 的类型是 DWORD,C# 中的 uint。
奇怪的是,您没有收到有关此问题的 PInvokeStackImbalance 调试器警告。这表明您正在 64 位操作系统上运行。这增加了几种额外的故障模式,您注入的 DLL 必须包含编译为您的进程和您想要挂钩的进程的正确位数的非托管代码。根据需要设置项目的平台目标。您的代码缺少所有错误检查,因此您不知道为什么它不起作用,当您收到失败返回代码时,请务必抛出 new Win32Exception() 。
That declaration is wrong. The type of the last argument (dwThreadId) is DWORD, an uint in C#.
Odd that you didn't get a PInvokeStackImbalance debugger warning about that. This suggests that you are running on a 64-bit operating system. Which adds several additional failure modes, the DLL you inject must contain unmanaged code compiled to the correct bitness of both your process and the process you want to hook. Set the Platform target of your project as necessary. Your code is missing all error checking so you won't know why it doesn't work, be sure to throw new Win32Exception() when you get a failure return code.