2011-08-28 88 views
0

你好,并提前感谢任何人试图帮助。 我试图设置一个CBT的窗口钩子,这在我设置全局的时候工作的很好,但是当我尝试将它附加到单个线程时失败。据我所知,我在书中做了一切: - 我暴露了非托管dll的钩子程序 - 我的应用程序,dll和线程的进程都是32位 - 我使用的线程ID是正确的(已确认与间谍++)SetWindowsHookEx无法使用线程Id

当我试图从一个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 
    } 
+1

Marshal.GetLastWin32Error要说什么? –

+0

没有......(意思是0) – Orran

回答

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(),当你得到一个失败的返回码。

+0

起初它是uint而不是ulong,它不能和uint一起工作 – Orran

+0

请务必阅读我的答案的其余部分。 –

+0

Marshal.GetLastWin32Error返回0 ... – Orran