18

से "सभी अपवादों को तोड़ें" को कैसे सेट करें, मैं डीबगर में सीएलआर अपवादों को जल्दी से टॉगल करने के लिए एक एक्सटेंशन बनाना चाहता हूं।
मैंने कई दृष्टिकोणों की कोशिश की है, जिनमें से कोई भी संतोषजनक नहीं है।पैकेज

यहाँ मैं पहले से ही करने की कोशिश की है:

  1. ExceptionSettings.SetBreakWhenThrown (MSDN)
    यह बहुत धीमी है (this Connect issue देखें)। मैंने प्रश्न "Toggle “Break when an exception is thrown.” using macro or keyboard shortcut" से दृष्टिकोण की कोशिश की है और न ही विश्वसनीय रूप से काम करने लगते हैं: ज्यादातर मामलों में केवल शीर्ष स्तर का चेकबॉक्स सेट हो जाता है, और यह वास्तव में डिबगिंग के दौरान अपवादों को तोड़ता नहीं है।

  2. कॉल DTE.ExecuteCommand("Debug.Exceptions") खिड़की दिखाने के लिए, और कॉल SetWindowsHookEx (MSDN) सिर्फ इतना है कि इससे पहले कि इसे रोकने के लिए इससे पहले कि यह प्रतीत होता है (ताकि उपयोगकर्ता के लिए कोई फ़्लैश है) करने के लिए। ऐसा लगता है क्योंकि मैं संदेश को रोक सकता था और HWND प्राप्त कर सकता था। लेकिन ऐसा लगता है कि हैकी और खिड़की ठीक से हेरफेर करना आसान नहीं है (इसमें कस्टम चेकबॉक्स और SysTreeView32 के साथ SysListView32 का कुछ अजीब संयोजन है)। तो मैं इसे आखिरी मौका समाधान के रूप में छोड़ रहा हूं।

  3. किसी तरह प्रबंधित कोड के लिए IDebugEngine2 (MSDN) हो और IDebugEngine2.SetException (MSDN) डिबगिंग सत्र के प्रारंभ में कहते हैं। ऐसा लगता है, लेकिन मुझे डीबग इंजन प्राप्त करने में समस्याएं आ रही हैं। मैंने IVsLoader के साथ on MSDN forums वर्णित दृष्टिकोण की कोशिश की है, लेकिन मुझे पूरा यकीन है कि यह मुझे डिबगिंग सत्र से संबंधित एक नया उदाहरण देता है।

    मैंने यहां सवाल भी पूछा है: "Visual Studio: How to get IDebugEngine2 from VS Package (except IVsLoader)", लेकिन समाधान नहीं मिला।

    मैं IVsDebugger.AdviseDebugEventCallback (MSDN) का उपयोग कर की कोशिश की है और IDebugEventCallback2 (MSDN) के कार्यान्वयन में गुजर, लेकिन मैं हमेशा pEngine के लिए null (और कोई IDebugEngineCreateEvent2 या तो) हो रही है।

    मैं IDebugSessionCreateEvent2 (undocumented?) और इसे से IDebugSession2 प्राप्त कर सकते हैं, लेकिन इसकी SetException कॉल हमेशा मुझे गलत तर्क के लिए एक HRESULT देता है, तो मैं यहाँ (IVsLoader से इंजन पर SetException बुला कुछ कमी हो सकती है ठीक देता मिलता है, बस काम नहीं करता)।

क्या कोई अन्य दृष्टिकोण है जो उन लोगों से बेहतर है या क्या मैंने मौजूदा लोगों में कुछ याद किया है?


अद्यतन/नोट: Exception Breaker:
आप इस प्रश्न पाया क्योंकि आप एक तेजी से "सभी अपवाद पर तोड़" चाहते हैं, मैं एक नि: शुल्क विस्तार आप दृश्य स्टूडियो गैलरी से प्राप्त कर सकते हैं बना दिया है।

+2

तुम बस +1 प्रयास आप इस प्रश्न में डाल के लिए की तुलना में अधिक के लायक है, तो मैं पिछले 3 एक संभावित समाधान पर काम के घंटे में डाल दिया। :) मेरा मानना ​​है कि यह केवल वीएस2012 पर ही लागू हो सकता है लेकिन उम्मीद है कि हम इसे 2010 में भी प्राप्त कर सकते हैं। –

+0

मैं वास्तव में आपकी मदद की सराहना करता हूं! मेरे कौशल ने वर्तमान में निम्न स्तर की डीबगिंग पर अपनी सीमा को मारा, इसलिए मैं वहां फंस गया था। मुझे आशा है कि यह विस्तार लोगों को शोध करने में खर्च करने से ज्यादा समय बचाएगा। –

उत्तर

9

प्रश्न से बाहर ऑटोमेशन इंटरफेस हैं। उनका उपयोग करके प्रदर्शन में सुधार करने के प्रयास में, मैंने अपवाद समूह से ExceptionSettings ऑब्जेक्ट और अपवाद नाम ExceptionSetting ऑब्जेक्ट में कैश बनाया।यह मैं SetBreakWhenThrown फोन करने के लिए अलग-अलग अपवाद के तेजी से देखने के लिए ExceptionSettings.Item बायपास करने के लिए अनुमति दी है, लेकिन दुर्भाग्य से SetBreakWhenThrown की आंतरिक कार्यान्वयन तर्क, जो बारी में एक आंतरिक गणन प्रक्रिया है कि इस पूरे दृष्टिकोण विपत्तियां चलाता है मान्य करने के लिए एक फोन भी शामिल है। कैश एक मैक्रो का उपयोग न करने वाले कोड से लगभग 4 गुना तेज है, लेकिन हम अभी भी कोड के बारे में बात कर रहे हैं जो कई मिनटों के लिए आईडीई लटकाएगा ...

नोट: नीचे दिए गए निर्देश केवल परीक्षण के साथ परीक्षण किए गए थे स्टूडियो 2012.

SetBreakWhenThrown के माध्यम से अलग-अलग दृश्यों में कदम उठाने से पता चला कि महत्वपूर्ण आंतरिक कॉल (सत्यापन के बाद) sdm::CDebugManager::SetException है। ऐसा लगता है कि खोल डीबगर (SVsShellDebugger सेवा है जो आप IVsDebugger लिए डाली) को लागू करता है IDebuggerInternal जो वर्तमान IDebugSession3 तक पहुँच प्रदान करता। एक समाधान खोलने के बाद, लेकिन मैंने डीबगिंग शुरू करने से पहले यह संपत्ति गैर-शून्य थी।

IDebuggerInternal debugger = Package.GetGlobalService(typeof(SVsShellDebugger)) as IDebuggerInternal; 
IDebugSession3 session = debugger != null ? debugger.CurrentSession : null; 

नोट: IDebuggerInternal इंटरफ़ेस में परिभाषित किया गया है:

Microsoft.VisualStudio.Debugger.Interop.Internal, Version=11.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 

EnumSetExceptions द्वारा लौटाए जानकारी का उपयोग कर, मैं एक संरचना है कि सफलतापूर्वक एक CLR अपवाद के लिए सेटिंग्स में हेरफेर बनाया! IDebugSession3.SetException से पर कॉल करें अपवाद फेंकने पर डीबगर रोकना सक्षम करें।

EXCEPTION_INFO[] exceptionInfo = 
{ 
    new EXCEPTION_INFO() 
    { 
     bstrExceptionName = typeof(NullReferenceException).FullName, 
     bstrProgramName = null, 
     dwCode = 0, 
     pProgram = null, 
     guidType = VSConstants.DebugEnginesGuids.ManagedOnly_guid, 
     dwState = enum_EXCEPTION_STATE.EXCEPTION_STOP_FIRST_CHANCE 
      | enum_EXCEPTION_STATE.EXCEPTION_STOP_SECOND_CHANCE 
      | enum_EXCEPTION_STATE.EXCEPTION_JUST_MY_CODE_SUPPORTED 
      | enum_EXCEPTION_STATE.EXCEPTION_STOP_USER_FIRST_CHANCE 
      | enum_EXCEPTION_STATE.EXCEPTION_STOP_USER_UNCAUGHT 
    } 
}; 
hr = session.SetException(exceptionInfo); 

अक्षम डिबगर हॉल्टिंग करने के लिए, IDebugSession3.RemoveSetException बजाय का उपयोग करें।

+0

यह आश्चर्यजनक है, बहुत बहुत धन्यवाद! मुझे वास्तव में पता चला कि 'AdviseDebugEventCallback' + 'IDebugSessionCreateEvent2' बस काम करता है, जब तक मैं' enum_EXCEPTION_STATE.EXCEPTION_STOP_ALL' के बजाय अपने झंडे संयोजन का उपयोग करता हूं। और सबसे अच्छा हिस्सा यह है कि अपवाद संवाद भी उस परिवर्तन को नोटिस करता है, इसलिए मुझे इसे पहले संस्करण में बदलने की आवश्यकता नहीं है। –

+0

एक मुद्दा मिला। जब मैं 'SetException' कहता हूं, तो यह' डीबग-> अपवाद 'की सामग्री को प्रभावित करता है और आम तौर पर काम करता है, लेकिन वर्तमान सत्र के दौरान नहीं। उदाहरण के लिए, यदि मैं एक कंसोल ऐप खोलता हूं, सत्र (चलिए इसे सत्र 1 कहते हैं) तुरंत * * .vshost.exe' के लिए बनाया जाता है - तब जब मैं 'रन' दबाता हूं, उसी सत्र का उपयोग किया जाता है, तो इसे फिर से बनाया जाता है 'रोकें' (सत्र 2)। तो जबकि 'डीबग-> अपवाद' मेरी सेटिंग दिखाते हैं, सत्र 1 इसे तोड़ता नहीं है - लेकिन सत्र 2 इसे फिर से सेट किए बिना भी करता है। –

+0

तो 'SetException' सत्रों के बीच बने कुछ आंतरिक विकल्प को प्रभावित करता है, लेकिन वर्तमान सत्र तुरंत इस विकल्प को पुनः लोड नहीं करता है। मुझे लगता है कि 'डीबग-> अपवाद' किसी प्रकार की पुन: प्रारंभ/अद्यतन विधि को कॉल करता है, लेकिन मुझे एपीआई में उपयुक्त कुछ भी नहीं मिल रहा है। –