如何将C ++ SetWindowsHookEx移植到C#或这是不可能的?

时间:2012-07-02 23:00:51

标签: c# winapi setwindowshookex

我在查看Microsoft KB318804中的示例,但他们使用“当前”应用程序的threadId!我有一些C ++代码可以工作,但我们必须重写它,我宁愿在C#中重写,而我在那里。它做的一件事是获取目标应用程序的threadId,如下所示:

uint lastId = GetWindowThreadProcessId(targetHandle, IntPtr.Zero);

不,GetCurrentThread不是正确的调用,因为我正在获取远程应用程序的线程ID,这是我们今天所做的以及我们想要做的事情。 targetHandle是该远程应用程序的句柄。

我将这个lastId转换为int并尝试连接C#代码,但SetWindowsHookEx返回0并失败。只有AppDomain.GetCurrentThreadId()似乎可以工作(即使它已被弃用,但替换虽然也不起作用)。

那么我必须使用C ++代码吗?或者有没有办法让它在C#中工作?

目前我们在C ++中使用其他应用程序注册hookhandler并返回事件。

2 个答案:

答案 0 :(得分:2)

您是否已查看pinvoke.net entry for SetWindowsHookEx

如果SetWindowsHookEx返回NULL,您应该致电GetLastError,因此在C#中您应该致电Marshal.GetLastWin32Error(假设DllImportAttribute.SetLastError包含在{ P / Invoke签名。)

来自pinvoke.net:

<强>特征

[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr SetWindowsHookEx(HookType hookType, HookProc lpfn, IntPtr hMod, uint dwThreadId);

<强>调用

IntPtr hHook;

using (Process process = Process.GetCurrentProcess())
using (ProcessModule module = process.MainModule)
{
    IntPtr hModule = GetModuleHandle(module.ModuleName);

    hHook = SetWindowsHookEx(HookType.WH_KEYBOARD_LL, hook, hModule, 0);
}

可能相关的问题:

答案 1 :(得分:0)

使用此kernel32调用获取当前线程ID:

    [DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
    public static extern int GetCurrentThreadId();