2009-09-23 14 views
5

मैंने WM_MOUSE पर एक वैश्विक हुक परिभाषित किया जो कुछ समय के लिए पूरी तरह से काम करता है। जब भी माउस चलता है तो यह एक विशिष्ट विंडो में एक संदेश पोस्ट करता है।SetWindowsHook कुछ समय के बाद काम करना बंद कर देता है

कुछ यादृच्छिक समय के बाद हुक संदेश भेजना बंद कर देता है। अगर मैं हुक पंजीकरण और हुक पंजीकृत करता हूं तो यह फिर से काम करता है। मुझे लगता है कि विंडोज़ में होने वाली कुछ विशिष्ट चीज हुक को रोकने का कारण बनती है, लेकिन मुझे वह नहीं मिल रहा है।

कोई विचार?

संपादित करें: जब मैं हुक सक्रिय नहीं होता तब मैंने अन्य प्रक्रियाओं में डीबगर संलग्न किया, और मैंने देखा कि अब डीएलएल लोड नहीं होता है।

क्या हुक डीएलएल को उतारने का कारण बन सकता है?

EDIT2: मुझे लगता है कि MouseHookProc में एक क्रैश किसी भी प्रक्रिया में dll हर प्रक्रिया उस में भरी हुई है से हुक dll उतारना पता लगाने के मैं अपने कोड में एक दुर्घटना के लिए एक कारण नहीं मिल रहा।। कुछ दौड़ की स्थिति या कुछ हो सकता है? यहां हुक डीएल कोड है:

#include "stdafx.h" 

// define a data segment 
#pragma data_seg(".SHARED") 
HWND hwnd=0; 
HHOOK hHook=0; 
#pragma data_seg() 

// tell the linker to share the segment 
#pragma comment(linker, "/section:.SHARED,RWS") 

#define WM_MOUSEHOOK   WM_USER+0x100 

HINSTANCE hInstance=0; 


// this allow to build a very small executable without any extra libraries 
// (probably not the problem, the bug still occurs without this) 
#ifndef _DEBUG 
void *__cdecl operator new(unsigned int bytes) 
{ 
    return HeapAlloc(GetProcessHeap(), 0, bytes); 
} 

void __cdecl operator delete(void *ptr) 
{ 
    if(ptr) HeapFree(GetProcessHeap(), 0, ptr); 
} 

extern "C" int __cdecl __purecall(void) 
{ 
    return 0; 
} 
#endif 

BOOL APIENTRY DllMain(HINSTANCE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) 
{  
    hInstance=hModule; 
    return TRUE; 
} 

LRESULT CALLBACK MouseHookProc(int nCode, WORD wParam, DWORD lParam) 
{ 
    if(nCode==HC_ACTION && (wParam==WM_MOUSEMOVE || wParam==WM_NCMOUSEMOVE)) 
    {    
     MSLLHOOKSTRUCT *mhs=(MSLLHOOKSTRUCT*)lParam;   
     PostMessage(hwnd, WM_MOUSEHOOK, wParam, 0); 
    } 
    return CallNextHookEx(hHook,nCode,wParam,lParam); 
} 

extern "C" __declspec(dllexport) HHOOK InitializeWindowsHook(char *title) 
{ 
    hwnd=FindWindow(0, title); 
    if(hwnd) 
     hHook=SetWindowsHookEx(WH_MOUSE, (HOOKPROC)MouseHookProc, hInstance, 0); 
    return hHook; 
} 

extern "C" __declspec(dllexport) BOOL DeinitializeWindowsHook() 
{ 
    if(hHook) { 
     BOOL b=UnhookWindowsHookEx(hHook); 
     hHook=0; 
     return b; 
    } 
    return FALSE; 
} 
+0

क्या आप श्रृंखला में अन्य हुक में संदेशों का प्रचार कर रहे हैं? – rpg

+0

मैंने देखा कि जब आपके पास 'WH_MOUSE' हुक है तो आप' MOUSEHOOKSTRUCT' संरचना के बजाय 'MSLLHOOKSTRUCT' का उपयोग करते हैं। –

+0

असल में आप '* एमएचएस 'घोषित करते हैं लेकिन आप इसका उपयोग नहीं करते हैं। –

उत्तर

2

क्या आपने जांच की है, अगर हुक अभी भी स्थापित है, तो इसे अब और नहीं कहा जाता है (यानी BOOL UnhookWindowsHook से वापसी मूल्य की जांच करें)?

संभवतः एक और हुक स्थापित है जो आपके हुक को सुरक्षित नहीं करता है, कॉलनक्स्टहूकएक्स() को कॉल नहीं करता है।

+0

जैसा कि आप देख सकते हैं कि मैं हर मामले में एक CallNextHookEx करता हूं। UnhookWindowsHook सबसे अच्छा वापस लौटने की संभावना है क्योंकि मेरे पास कुछ लॉग हैं, कुछ भी लॉग नहीं किया गया था। –

+0

* आप * CallNextHookEx पर कॉल करते हैं, लेकिन मेरी धारणा यह थी कि कहीं और एक अलग हुक स्थापित है, जो CallNextHookEx को कॉल नहीं करता है। मुझे नहीं पता कि यह एक बड़ी परियोजना है, जहां आप शायद एक टीम के भीतर सहयोग कर सकते हैं। यदि ऐसा है, तो SetWindowsHookEx के लिए सभी कोड स्कैन करें। –

0

क्या आपके साझा क्षेत्र में आपके हुक के लिए आवश्यक डेटा है? कम से कम यह लक्ष्य विंडो के HHOOK और HWND होगा जो अधिसूचना संदेश प्राप्त करता है।

+0

हां हुक पूरी तरह से काम करता है, कभी-कभी सभी खिड़कियों और थ्रेड पर, फिर यह काम करना बंद कर देता है। –

1

इसके बजाय WH_MOUSE_LL का उपयोग करने का प्रयास करें।

संपादित करें: के बारे में LowLevelMouseProc Function

हुक प्रक्रिया डेटा रजिस्ट्री कुंजी निम्नलिखित प्रविष्टि में LowLevelHooksTimeout मूल्य में निर्दिष्ट की तुलना में कम समय में एक संदेश संसाधित करना चाहिए:

HKEY_CURRENT_USER\Control Panel\Desktop

मूल्य मिलीसेकंड में है। यदि हुक प्रक्रिया के दौरान इस अंतराल के दौरान वापस नहीं आती है, तो सिस्टम अगले हुक में संदेश पास करेगा।

+0

मैंने कोशिश की लेकिन यह इतनी बार आग लगती है कि यह सभी अनुप्रयोगों को धीमा कर देती है और क्या यह कुछ हल करेगी? –

+1

@ ईमानुअल कारदेक, आपको हुक प्रक्रिया के अंदर * भारी * काम नहीं करना चाहिए (एक समय सीमा है)। नौकरी करने के लिए कुछ अन्य दिनचर्या को सूचित करें (शायद एक संदेश पोस्ट करने के माध्यम से) और तुरंत लौटें। –

+0

वास्तव में केवल एक चीज जो मैं पहले से ही जानता हूं कि एक संदेश भेज रहा है। Wm_mouse ने मेरे लिए काम करने के बाद से wh_mouse_ll के साथ बहुत कुछ जांच नहीं की थी। Wh_mouse के साथ क्या समस्या है? –

1

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

मेरा सुझाव है कि आप अपने डीएलएल के अंदर पहली चीज को अपने आप पर LoadLibrary पर कॉल करना है, ताकि डीएलएल की संदर्भ गणना जिसमें हुक फ़ंक्शन शामिल हो, एक से बढ़ जाए। सुनिश्चित करें कि इस सिद्धांत का परीक्षण करने के लिए FreeLibrary पर कॉल न करें।

1

आपको अपने हुक हैंडल बीटीडब्ल्यू को बंद करना चाहिए।

एकमात्र चीज जिसे मैं सोच सकता हूं, दुर्घटना का कारण बनता है यदि आपका हुक हैंडल नष्ट हो गया है।क्या आप अपवाद को फंस सकते हैं? क्या अपवाद होने पर अपवाद पर ब्रेक करने का प्रयास किया गया है? यदि आपको नहीं पता कि क्या अपवाद हो रहा है, तो आपने अंततः अपने कोड के चारों ओर एक __try/__ जोड़ने की कोशिश की है?

+0

मैं आज __try/__ अंततः ब्लॉक जोड़ दूंगा। मुझे लगता है कि एक दुर्घटना है क्योंकि इससे वही व्यवहार होगा। मैंने एक शून्य सूचक को dereferencing करने की कोशिश की और यह हर लोड हुक डीएलएल के उतारने का कारण बनता है। विंडोज़ शायद एक __try जोड़ते हैं, __ आखिरकार हुक के आसपास ब्लॉक करते हैं ताकि वे बुरी तरह व्यवहार कर सकें। –

+0

मुझे क्लोज़ैंडल कब करना चाहिए? Unhookwindowsex के बाद? –

+0

बिल्कुल। हर हैंडल के लिए आप "बनाते हैं" तो आपको इसे बंद करना चाहिए। मुझे पूरा यकीन है कि FindWindow केवल आपको एक पूर्व-मौजूदा हैंडल देता है, इसलिए इसे बंद करने की आवश्यकता नहीं है। मेरा मानना ​​है कि भ्रम है क्यों COM ने पूरी addref/रिलीज चीज पेश की :) – Goz

0

पार्टी के लिए देर से आ रहा है लेकिन मुझे भी एक ही समस्या का सामना करना पड़ा और मेरे कार्यों को निष्पादित करने और प्रक्रिया के रूप में वापस आने के लिए एक नया थ्रेड बनाकर हल किया गया। उम्मीद है कि यह किसी की मदद करता है।

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

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