2012-09-12 25 views
3

我的任務是監視從初始程序產生的所有GUI程序中的活動,並在一段時間內變爲非活動狀態時將其殺死。這不能是系統活動,因爲即使用戶剛剛使用另一個程序(而不是由初始程序產生),我們也必須關閉這些程序。應用程序產卵過程是一個.Net程序,不會改變。我能夠使用SetWindowsHookEx從.Net設置低級別掛鉤(WH_KEYBOARD_LLWH_MOUSE_LL),但不確定如何將消息與我已啓動的進程關聯(使用System.Diagnostics.Process。)我可以掛鉤應用程序中的事件進行掛接,但是當我試圖掛鉤到一個特定的線程產生程序時,它總是會失敗。如何在我生成的過程中監控活動?

我能來的最接近的是通過創建一個代表.Net程序調用SetWindowsHookEx的C++ dll。使用這種方法,我可以掛鉤產生的notepad.exe的第一個線程,但回調函數從不被調用。如果我指定線程ID爲0,則在原始應用程序中存在活動時調用回調,因此我知道SetWindowsHookEx在這種情況下適用。

我還沒完全理解鉤子,但是從我讀過的這個將不起作用,因爲dll回調函數地址對於掛鉤進程將沒有意義。這是我遇到的問題嗎?如果是這樣,有沒有辦法解決這個問題,或者有人可以建議一個替代方案來確定一個產生的過程是否被積極使用?

。NET(C#)代碼:

private const int WH_MOUSE = 14; 

[DllImport("TestHook.dll", EntryPoint="InitializeHook", SetLastError=true, CharSet=CharSet.Unicode, ExactSpelling=true, CallingConvention=CallingConvention.StdCall)] 
private static extern bool InitializeHook(uint hookType, int threadID); 

private void HookEm() { 
    //... 
    System.Diagnostics.Process testProcess = System.Diagnostics.Process.Start("notepad"); 
    if(!InitializeHook(WH_MOUSE, testProcess.Threads[0].Id)) // The notepad.exe thread I know hooks 
     MessageBox.Show("Boom!"); 
    //... 
} 

C++ DLL:

HHOOK hookValue; 

bool InitializeHook(UINT hookID, int threadID) { 
    //... Determining which callback to use 
    hookValue = SetWindowsHookEx(hookID, (HOOKPROC)MouseHookCallback, _dllInstance, threadID); 
    //... 
    return hookValue != NULL 
} 

static LRESULT CALLBACK MouseHookCallback(int code, WPARAM wparam, LPARAM lparam) { 
    //From what I can see, this is never touched when hooking a thread on an outside process 
} 

所有這一切都正在32位Windows XP的計算機上完成。我明白,需要單獨的64位dll來處理64位應用程序。

+0

你的實際'InitializeHook'是否返回正確的'SetWindowsHookEx'結果? – Rost

+0

我忘了把它放在那裏,但是C++ dll不會跟蹤來自'SetWindowsHookEx'的返回值,只有當'SetWindowsHookEx'返回一個非空值時,'InitializeHook'的返回值纔是true – BlueBayliss

回答

1

對於任何遇到類似問題的人,我們的最終解決方案是使用GetWindowThreadProcessId(GetForegroundWindow(), ref foregroundWindowProcessId)間隔檢查前景窗口並保留我們衍生的進程標識的映射。每當這個定時器觸發時,我們設置一個布爾值來檢查函數CallNextHookEx,因爲它必須是高效/快速的,否則Windows將解除我們的聯繫。然後,我們使用上面的布爾值和系統掛鉤SetWindowsHookEx來確定用戶是否在我們的應用程序中處於活動狀態。此解決方案不需要C++ dll。