visual tools studio serial para full for español debug configurar code .net visual-studio-2010 visual-studio visual-studio-debugging visual-studio-extensions

.net - tools - php visual studio free



Cómo configurar "Romper todas las excepciones", de un paquete (1)

Quiero hacer una extensión para alternar rápidamente entre las excepciones CLR en el depurador.
He intentado varios enfoques, ninguno de los cuales es satisfactorio.

Esto es lo que ya he intentado:

  1. ExceptionSettings.SetBreakWhenThrown ( MSDN )
    Esto es extremadamente lento (vea este problema de conexión ). Probé los enfoques de la pregunta " Alternar" Descanso cuando se lanza una excepción "utilizando el método abreviado de teclado o macro " y ninguno parece funcionar de manera confiable: en la mayoría de los casos solo se establece la casilla de verificación de nivel superior, y no se rompe en las excepciones cuando se depura .

  2. Llame a DTE.ExecuteCommand("Debug.Exceptions") para mostrar la ventana, y llame a SetWindowsHookEx ( MSDN ) justo antes de eso para interceptarlo antes de que aparezca (para que no haya flash para el usuario). Esto parece posible ya que pude interceptar el mensaje y obtener HWND . Pero parece hacky y Window no es tan fácil de manipular correctamente (tiene una extraña combinación de SysListView32 con casillas de verificación personalizadas y SysTreeView32 ). Así que lo dejo como una solución de última oportunidad.

  3. De alguna manera, obtenga IDebugEngine2 ( MSDN ) para el código administrado y llame a IDebugEngine2.SetException ( MSDN ) al comienzo de la sesión de depuración. Esto parece posible, pero estoy teniendo problemas para obtener un motor de depuración. He intentado acercarme con IVsLoader descrito en los foros de MSDN , pero estoy bastante seguro de que me da una nueva instancia no relacionada con la sesión de depuración.

    También hice la pregunta aquí: " Visual Studio: cómo obtener IDebugEngine2 del paquete VS (excepto IVsLoader) ", pero no obtuve una solución.

    He intentado usar IVsDebugger.AdviseDebugEventCallback ( MSDN ) y paso la implementación de IDebugEventCallback2 ( MSDN ), pero siempre pEngine null para pEngine (y tampoco IDebugEngineCreateEvent2 ).

    Obtengo IDebugSessionCreateEvent2 (¿indocumentado?) Y puedo obtener IDebugSession2 de él, pero su llamada SetException siempre me da un HRESULT por argumento incorrecto, por lo que me puede faltar algo aquí (llamar a SetException en el motor de IVsLoader da OK, simplemente no funciona) .

¿Hay algún otro enfoque que sea mejor que esos o me he perdido algo en los existentes?

ACTUALIZACIÓN / NOTA:
Si encontró esta pregunta porque quiere un "Break on All Exceptions" más rápido, he creado una extensión gratuita que puede obtener de Visual Studio Gallery: Exception Breaker .


Las interfaces de automatización están fuera de cuestión . En un intento por mejorar el rendimiento al usarlos, creé un caché del grupo de ExceptionSettings objeto ExceptionSettings y el nombre de la ExceptionSetting objeto ExceptionSetting . Esto me permitió omitir ExceptionSettings.Item para búsqueda rápida de excepciones individuales para llamar a SetBreakWhenThrown , pero desafortunadamente la implementación interna de SetBreakWhenThrown incluye una llamada para validar los argumentos, que a su vez desencadena un proceso de enumeración interno que afecta a todo este enfoque. El caché es aproximadamente 4 veces más rápido que el código que no usa una macro, pero todavía estamos hablando de un código que colgará el IDE durante varios minutos ...

NOTA: Las instrucciones siguientes solo se probaron hasta ahora con Visual Studio 2012.

SetBreakWhenThrown por SetBreakWhenThrown en la vista de desensamblaje reveló que la llamada interna crítica (después de la validación) es sdm::CDebugManager::SetException . Resulta que el depurador de shell (servicio SVsShellDebugger que se IVsDebugger a IVsDebugger ) implementa IDebuggerInternal que proporciona acceso al IDebugSession3 actual. Esta propiedad no era nula después de abrir una solución, pero antes de que comenzara la depuración.

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

Nota: La interfaz IDebuggerInternal se define en:

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

Usando información devuelta por EnumSetExceptions , ¡creé una estructura que altera con éxito la configuración de una excepción CLR! Llame a IDebugSession3.SetException para habilitar la detención del depurador cuando se lanza la excepción.

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);

Para desactivar la detención del depurador, use IDebugSession3.RemoveSetException en IDebugSession3.RemoveSetException lugar.