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



我正在查看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++并返回事件。

您是否查看了SetWindowsHookEx的 pinvoke.net 条目?

如果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);
}

可能相关的问题:

  • 调用外部 SetWindowsHookEx 和 GetModuleHandle 时出错

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

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

相关内容

最新更新