您好,并提前感谢任何试图提供帮助的人。 我正在尝试设置一个CBT窗口挂钩,这在我全局设置时效果很好,但每当我尝试将它附加到单个线程时都会失败。据我所知,我正在做这本书的一切: - 我从一个非托管的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
}
答案 0 :(得分:3)
[DllImport( "user32.dll", SetLastError = true )]
static extern IntPtr SetWindowsHookEx ( int hookType, UIntPtr lpfn,
IntPtr hMod, ulong dwThreadId );
该声明是错误的。最后一个参数的类型(dwThreadId)是DWORD,C#中的一个uint。
奇怪的是你没有得到关于它的PInvokeStackImbalance调试器警告。这表明您运行的是64位操作系统。其中添加了几个额外的故障模式,您注入的DLL必须包含非托管代码,这些代码编译为您的进程和要挂接的进程的正确位数。根据需要设置项目的平台目标。您的代码缺少所有错误检查,因此您不知道它为什么不起作用,请确保在收到失败的返回代码时抛出新的Win32Exception()。