2009-06-08 12 views
5

चीजों का एक गुच्छा करने की कोशिश की लेकिन मैं अपने टास्कबार को मेरे डेस्कटॉप यूआई पर नियुक्त और अन्य अलौकिक प्रभावों के बीच लगातार काम नहीं कर सकता।"विंडोज हुक" सिस्टम को कैसे जोड़ा जाए ताकि विंडोज़ को बनाया/सक्रिय किया जा सके?

पहले ओपन-लाइब्रेरी http://mwinapi.sourceforge.net/ का उपयोग करने का प्रयास किया। हालांकि यह विंडोज़ और सामान की गणना के लिए एक ओओ परत के रूप में अच्छी तरह से काम किया। यह हुक ठीक से नहीं कर सका

अगला स्टॉप Dino E.'s post on Windows Hooks in the .Net framework था। मैंने अपना खुद का प्रकार लिखना समाप्त कर दिया क्योंकि मैं पाठ को समझ रहा था और इसे काम करने की कोशिश कर रहा था।

मेरा इरादा यह ऐप चलाना है और यह चलाते समय सभी बनाई गई विंडो को लॉग इन करने में सक्षम है। सभी आंखों रही है ...

अद्यतन: कतरना जाहिरा तौर पर आप can't write global windows hooks in .Net के बाद से/प्रबंधित कोड (कुछ निम्न स्तर माउस या कीबोर्ड हुक को छोड़कर)

तो मैं सेल्सियस तक ++ का बदला है। फिर भी सभी WinAPI कॉल वैध हैंडल लौटाते हैं लेकिन मुझे मेरा फ़िल्टर फ़ंक्शन नहीं दिख रहा है - ऐसा लगता है कि कोई सूचना प्राप्त नहीं हो रही है। अभी भी काम नहीं करता ... क्या कोई गलती को देख सकता है।

void CWinHookFacade::Hook() 
{ 
    HMODULE hCurrentDll = LoadLibrary(_T("[Path to my hook dll]")); 
    m_HookHandle = SetWindowsHookEx(WH_CBT, 
     FilterFunctionForHook, 
     hCurrentDll, 
     0); 
    if (m_HookHandle == NULL) 
    { 
     throw new std::exception("Unable to hook"); 
    } 

} 
void CWinHookFacade::Unhook() 
{ 
    if (!UnhookWindowsHookEx(m_HookHandle)) 
    { 
     throw new std::exception("Unhook failed!"); 
    } 
    m_HookHandle = NULL; 
} 

LRESULT CWinHookFacade::FilterFunctionForHook(int code, WPARAM wParam, LPARAM lParam) 
{ 
    if (code >= 0) 
    { 
     switch(code) 
     { 
     case HCBT_CREATEWND: 
      wprintf(_T("Created Window")); 
      break; 
     case HCBT_ACTIVATE: 
      wprintf(_T("Activated Window")); 
      break; 
     case HCBT_DESTROYWND: 
      wprintf(_T("Destroy Window")); 
      break; 
     } 
    } 

    return CallNextHookEx(m_HookHandle, code, wParam, lParam); 
} 

ग्राहक exe इस

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    CWinHookFacade::Hook(); 
    getchar(); 
    CWinHookFacade::Unhook(); 
} 
+0

स्पष्टीकरण के लिए - SetWindowsHookEx हर बार एक मान्य हैंडल देता है। अगर कोई भी इसे आजमा देना चाहता है, तो उपरोक्त कोड में कोई अन्य निर्भरता नहीं है। एक रिक्त प्रोजेक्ट में एक .cs फ़ाइल में पेस्ट करें और चलाएं। – Gishu

उत्तर

5

मैं समस्याओं आपको हो रही हैं क्योंकि आप सी # में एक हुक समारोह को लागू करने की कोशिश कर रहे लगता है जैसे Hook_DLL कहता है। पर SetWindowsHookEx() पर आधारित, यह कहता है कि आप ऐसा नहीं कर सकते - हुक प्रक्रिया एक अप्रबंधित डीएलएल में होनी चाहिए। अन्यथा, यह आपके डीएलएल को एक संदेश लूप के साथ सभी चल रही प्रक्रियाओं में लोड करेगा, जिससे बदले में सीएलआर लोड हो जाएगा और प्रत्येक प्रक्रिया में शुरू किया जाएगा। न केवल इसमें काफी समय लगेगा, लेकिन सीएलआर को सभी प्रक्रियाओं में इंजेक्शन देने का शायद सबसे अच्छा विचार नहीं है। इसके अलावा, क्या होता है यदि किसी प्रक्रिया में पहले से चलने वाला सीएलआर है जो आपके डीएलएल के खिलाफ बनाया गया था उससे अलग है?

सबसे अच्छा तरीका इस कोड को एक अप्रबंधित सी ++ डीएलएल में स्थानांतरित करना होगा, और आपके आवेदन पर वापस अपनी हुक प्रक्रिया द्वारा अवरुद्ध डेटा भेजने के लिए कुछ प्रकार के इंटरप्रोसेस संचार का उपयोग करना होगा।

अद्यतन

सबसे पहले, क्यों आप अपने DLL के HINSTANCE पाने के लिए LoadLibrary() बुला रहे हैं (और यह शायद नहीं आपकी समस्या का कारण है)? GetModuleHandle() पर कॉल करना शायद बेहतर होगा क्योंकि आपका डीएलएल पहले ही लोड हो चुका है।

क्यों आपकी हुक प्रक्रिया को कभी नहीं कहा जाता है - आपने यह कैसे सत्यापित किया है? चूंकि आप सिस्टम में सभी जीयूआई धागे लगा रहे हैं, इसका मतलब है कि आपके डीएलएल को सभी जीयूआई प्रक्रियाओं में लोड किया जाना चाहिए। यह संभावना है कि आपको wprintf() पर कॉल करने के नतीजे दिखाई नहीं देंगे क्योंकि अन्य प्रक्रियाओं में आउटपुट दिखाने के लिए कंसोल विंडो नहीं है।

यह सत्यापित करने के लिए कि आपका डीएलएल ठीक से लोड हो गया है, एक प्रोग्राम का उपयोग करें जो किसी प्रक्रिया द्वारा लोड किए गए डीएलएल को सूचीबद्ध करता है (मुझे Process Explorer पसंद है)। आप ढूँढें का उपयोग कर सकते हैं अपने डीएलएल के नाम की खोज के लिए हैंडल या डीएलएल मेनू आइटम ढूंढें - यह एक संदेश लूप के साथ सभी प्रक्रियाओं में दिखाना चाहिए।

एक बार जब आप यह सत्यापित कर लें कि आपका डीएलएल लोड हो गया है, तो यह देखने के लिए कि क्या आपका हुक कहा जाता है, आप किसी अन्य प्रक्रिया (जैसे नोटपैड) में डीबगर संलग्न कर सकते हैं, और फिर अपने हुक फ़ंक्शन में ब्रेकपॉइंट सेट कर सकते हैं। जब भी सीबीटी हुक में कोई संदेश भेजा जाता है तो उसे छोड़ना चाहिए। यदि आप डीबगर का उपयोग नहीं करना चाहते हैं, तो आप परिणामों को मॉनिटर करने के लिए wprintf() से OutputDebugString() पर कॉल बदल सकते हैं और DebugView जैसी उपयोगिता चला सकते हैं।

अंत में, चूंकि आपके हुक फ़ंक्शन को किसी अन्य प्रक्रिया के संदर्भ में बुलाया जाता है, इसलिए आपका m_HookHandle चर मान्य नहीं होगा। आपको इसे shared data segment में संग्रहीत करना चाहिए ताकि आपके डीएलएल के सभी लोड किए गए उदाहरणों का वही मूल्य होगा।

+0

मुझे इंजेक्शन भाग के बारे में पता था - मेरा कोड डीएलएल में था। लेकिन यह नहीं पता था कि सी # में करना असंभव है। कल इसे सीपीपी में आज़माएं और पोस्ट करें कि यह कैसे जाता है ... मुझे पिनकोक पेज पर नोट्स सेक्शन को मेरे खतरे में पढ़ना याद आया। (मैंने पाया कि प्रबंधित थ्रेडिड भी कठिन तरीके से काम नहीं करता है) – Gishu

+0

एक और चीज जिसने मुझे फेंक दिया था वह था कि http://mwinapi.sourceforge.net/ लाइब्रेरी से हुक क्लास में एक ctor पैरामीटर है - bGlobal और पूरी तरह से प्रबंधित है। अजीब ... – Gishu

+0

भी अप्रबंधित करने के लिए स्विच किया गया - अभी भी काम नहीं लग रहा है। अपडेट किया गया मूल प्रश्न ... – Gishu

3

अंततः इसे एक ने खींचा। किसी को भविष्य में इसकी आवश्यकता होने पर इसे blog post के रूप में लिखा है।

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

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