.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:
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 .Llame a
DTE.ExecuteCommand("Debug.Exceptions")
para mostrar la ventana, y llame aSetWindowsHookEx
( 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 obtenerHWND
. Pero parece hacky y Window no es tan fácil de manipular correctamente (tiene una extraña combinación deSysListView32
con casillas de verificación personalizadas ySysTreeView32
). Así que lo dejo como una solución de última oportunidad.De alguna manera, obtenga
IDebugEngine2
( MSDN ) para el código administrado y llame aIDebugEngine2.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 conIVsLoader
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 deIDebugEventCallback2
( MSDN ), pero siemprepEngine
null
parapEngine
(y tampocoIDebugEngineCreateEvent2
).Obtengo
IDebugSessionCreateEvent2
(¿indocumentado?) Y puedo obtenerIDebugSession2
de él, pero su llamadaSetException
siempre me da unHRESULT
por argumento incorrecto, por lo que me puede faltar algo aquí (llamar aSetException
en el motor deIVsLoader
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.