2012-07-02 43 views
2

我在查看Microsoft KB318804中的示例,但它們使用「當前」應用程序的threadId!我有一些C++代碼可行,但我們必須重寫它,並且我寧願在C#中重新編寫代碼。有一件事它的作用是讓目標應用程序的的threadId像這樣:如何將C++ SetWindowsHookEx移植到C#或者這是不可能的?

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

沒有,GetCurrentThread是不是因爲我得到一個遠程應用程序的線程ID正確調用,它就是我們今天做,我們想要做什麼。 targetHandle是該遠程應用程序的句柄。

我把這個lastId強制轉換爲int並嘗試連接C#代碼,但SetWindowsHookEx返回0並失敗。只有AppDomain.GetCurrentThreadId()似乎工作(即使它已被棄用,但替換雖然不起作用)。

那麼我需要使用C++代碼嗎?或者有沒有辦法讓它在C#中工作?

當前我們在C++中註冊hookhandler與其他應用程序,並返回事件。

+0

更換爲AppDomain.GetCurrentThreadId( )將不起作用,因爲它不會返回操作系統的線程標識,而是返回一個託管線程標識。你能告訴更多關於你想要解決的問題嗎?如果你使用的是Winform或WPF? –

+2

你使用什麼類型的鉤子?除了_LL鉤子之外,對其他應用程序使用時,都要求鉤子處於單獨的DLL中,因此鉤子必須使用C++。你只能使用C#作爲_LL鉤子,或者(我認爲,但不是絕對肯定)鉤住你自己的進程。 – BrendanMcK

+0

@BrendanMcK shucks,我想這就是我發現的。我必須留在C++中,並用C++重寫它並保存在C++中。 :(:(。哦,我只是希望,因爲我必須重寫它,我可能會轉換它,但我猜不是。 –

回答

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

可能相關的問題:

+0

所以它看起來像我不能這樣做,正確嗎?這個聲明specfically我認爲暗示我不能將我的代碼連接到另一個應用程序(儘管我可以用C++這樣做)...「一個鉤子必須有一個本地動態鏈接庫(DLL)導出,以便將其自身注入另一個需要調用有效的一致函數的進程中。這需要一個DLL導出,.NET Framework不支持。」 –

0

使用此KERNEL32調用來獲取當前線程ID:

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

GetCurrentThreadId是「不是」我想要的。我得到了一個完全不同的應用程序的線程ID,而不是我的應用程序。目前的C++代碼工作,並閱讀文檔,我認爲它只能在C++中工作,目前這不能在C +/.NET中工作。 –

+0

@DeanHiller對不起,我沒有從原來的問題中得到。 – roken