2011-04-11 40 views
0

我一直在嘗試用C編寫一個DLL。DLL中的KeyboardHookProc在從python中調用時不會執行任何操作

安裝鉤子設置了KeyboardProc。調用Python中的InstallHook()UninstallHook()函數始終返回0,我想這是因爲我的回調函數KeyboardProc不起作用。

以下是該DLL我的C代碼:

#include "stdafx.h" 
#include <windows.h> 
#include <string.h> 
#include <ctype.h> 
#include <stdio.h> 
#include "ourdll.h" 

//#pragma comment(linker, "/SECTION:.SHARED,RWS") 
//#pragma data_seg(".SHARED") 
HHOOK hKeyboardHook = 0; 
int keypresses = 0; 
    HMODULE hInstance = 0; 

//#pragma data_seg() 

BOOL WINAPI DllMain (HANDLE hModule, DWORD dwFunction, LPVOID lpNot) 
{ 
      hInstance = hModule; //Edit 
    return TRUE; 
} 

LRESULT CALLBACK KeyboardProc(int hookCode, WPARAM vKeyCode, LPARAM flags) 
{ 
    if(hookCode < 0) 
    { 
     return CallNextHookEx(hKeyboardHook, hookCode, vKeyCode, flags); 
    } 

    keypresses++;; 

    return CallNextHookEx(hKeyboardHook, hookCode, vKeyCode, flags); 
} 

__declspec(dllexport) void InstallHook(void) 
{ 
    hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, hInstance, 0); 
} 

__declspec(dllexport) int UninstallHook(void) 
{ 
    UnhookWindowsHookEx(hKeyboardHook); 
    hKeyboardHook = 0; 
    return keypresses; 
} 

的Python代碼使用此如下:

>>> from ctypes import * 
>>> dll = CDLL('C:\...\OurDLL.dll') 
>>> dll.InstallHook() 

[在這一點上鍵入內容]

>>> result = dll.UninstallHook() 
>>> result 
0 

編輯:我應該提一下,我也試過了LowLevelKeyboardHook。我知道LowLevel掛鉤是全局的,並且會捕獲所有鍵擊,但是這隻會導致我的Python代碼在返回零之前凍結一兩秒鐘。

我不是C的專家,所以任何幫助將不勝感激。謝謝。

回答

1
hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, NULL, 0); 

SetWindowsHookEx需要一個hModule - 從DllMain保存hModule並將其傳遞到此處。 (只有當線程ID是你自己的線程時,纔可以傳遞NULL。)

對此的一個例外是_LL鉤子類型;這些不需要hmodule參數,因爲這些鉤子不會注入到目標進程中 - 這就是爲什麼使用KEYBOARD_LL的代碼是「成功」的原因。

至於爲什麼在使用KEYBOARD_LL時可能會阻塞 - LowLevelKeyboardHookProc的文檔中提到安裝鉤子的線程(即調用SetWindowsHookEx)必須有一個消息循環,您可能沒有在Python代碼中使用該循環。調試技巧:它看起來像SetWindowsHookEx應該返回NULL(與GetLastError()返回一個合適的錯誤代碼);在開發代碼時,使用適當的assert/printf/OutputDebugString組合來檢查這些返回值是確保您的假設是正確的併爲您提供有關錯誤發生的一些線索的好方法。

順便提一下,KEYBOARD與KEYBOARD_LL有一點需要注意:KEYBOARD掛鉤會被加載到目標進程中 - 但只有當它是相同的bitness - 所以32位掛鉤只能看到其他32位按鍵流程。 OTOH,KEYBOARD_LL在你自己的進程中被回調,所以你可以看到所有的鍵 - 也不需要處理共享段(儘管據我所知它的效率不如KEYBOARD掛鉤)。

+0

你說得對!我需要從DLLMain保存'HMODULE'類型。現在它在'KeyboardProc'回調函數中遞增我的'keypresses'值。共享段是我嘗試Lowlevel鍵盤時留下的代碼。對於我的草率代碼抱歉,我很慚愧,但在我開始使用它之前,我會先修復它。再次,非常感謝! – mmoore 2011-04-11 23:48:58

相關問題