¿Cómo puedo hacer una macro de Visual Studio para adjuntar el depurador a todas las instancias de w3wp.exe?
-
03-07-2019 - |
Pregunta
Normalmente estoy desarrollando aplicaciones web, y una cantidad sorprendentemente grande de mi tiempo de trabajo se dedica a hacer "Ctrl + Alt + P", ordenar por Nombre de proceso y seleccionar w3wp.exe para adjuntar mi depurador.
Para empeorar las cosas, estoy trabajando en una aplicación que abarca varios grupos de aplicaciones, por lo que normalmente tengo 2 o 3 instancias de w3wp.exe, y es imposible saber a cuál adjuntar, así que normalmente termino adjuntándolos a todos, lo que es una exageración pero funciona.
En general, esto es bastante molesto ...
Mi colega descubrió una manera de tener una macro VS para adjuntarla automáticamente a w3wp.exe (básicamente, grabó esto):
Sub AttachMacro()
Try
Dim dbg2 As EnvDTE80.Debugger2 = DTE.Debugger
Dim trans As EnvDTE80.Transport = dbg2.Transports.Item("Default")
Dim dbgeng(3) As EnvDTE80.Engine
dbgeng(0) = trans.Engines.Item("T-SQL")
dbgeng(1) = trans.Engines.Item("T-SQL")
dbgeng(2) = trans.Engines.Item("Managed")
Dim proc2 As EnvDTE80.Process2 = dbg2.GetProcesses(trans, "ENIAC").Item("w3wp.exe")
proc2.Attach2(dbgeng)
Catch ex As System.Exception
MsgBox(ex.Message)
End Try
End Sub
No estoy realmente seguro de si todo eso es necesario, o algo así, nunca he creado una macro para VS, realmente no sé por dónde empezar.
¿Habría una manera de modificar esta macro para que en lugar de adjuntarse a una instancia de w3wp.exe, se adjunte a todas instancias de w3wp. exe?
Solución
Sub MacroAttachToAllProcesses()
Try
Dim dbg2 As EnvDTE80.Debugger2 = DTE.Debugger
Dim trans As EnvDTE80.Transport = dbg2.Transports.Item("Default")
Dim dbgeng(3) As EnvDTE80.Engine
dbgeng(0) = trans.Engines.Item("T-SQL")
dbgeng(1) = trans.Engines.Item("T-SQL")
dbgeng(2) = trans.Engines.Item("Managed")
For Each theProcess As EnvDTE80.Process2 In dbg2.GetProcesses(trans, "COMPUTERNAME")
If theProcess.Name.Contains("w3wp.exe") Then
theProcess.Attach2(dbgeng)
End If
Next
Catch ex As System.Exception
MsgBox(ex.Message)
End Try
End Sub
Otros consejos
Sé que estás buscando una macro para esta tarea, y tengo macros similares. Sin embargo, me gustaría explicar una forma de adjuntar el depurador a los proyectos en su solución cuando empiece a depurar.
Es una característica poco conocida: si hace clic con el botón derecho en el archivo de la solución en el buscador de soluciones, Elegir propiedades, puede definir múltiples proyectos de inicio y su acción. Su depurador se adjuntará a los proyectos enumerados cuando lo ejecute.
Nota: si tienes un servicio web, se abrirá una ventana del navegador, sin embargo, puedes desactivarlo en las propiedades del proyecto indicándole que no abra una ventana.
Así es como me conecto a un proceso w3wp remoto. Se ejecuta un poco más rápido que la solución de DanC y tiene un manejo de errores adicional.
Private Sub AttachToW3wp(ByVal machineName As String)
' In order for this to work, you have to be running the Visual Studio 2010 Remote Debugging Monitor
' as your (domain) user.
' It won't work if the remote debugger is running as a service. I've tried every permutation of
' domain and username in the the transport qualifier, tried the obvious local system username,
' even tried looking at the network traffic
' in WireShark, I can't figure it out how to make it work if you are running as a service.
' If you are running the debugger as a service, even running the macro that gets created by VS's
' macro recorder when you attach to a process doesn't work.
Dim transportQualifier = machineName
Try
Dim processToAttachTo As String = "w3wp.exe"
Dim dbg2 As EnvDTE80.Debugger2 = DTE.Debugger
Dim trans As EnvDTE80.Transport = dbg2.Transports.Item("Default")
Dim dbgeng(2) As EnvDTE80.Engine
dbgeng(0) = trans.Engines.Item("T-SQL")
dbgeng(1) = trans.Engines.Item("Managed (v2.0, v1.1, v1.0)")
Dim processesRemote = dbg2.GetProcesses(trans, transportQualifier)
Dim attached As Boolean = False
Dim processRemote As EnvDTE80.Process2
For Each processRemote In processesRemote
' For some reason it takes a much longer time to get the remote process names then it
' does the user name, so let's skip over all the processes that have the wrong UserName.
If processRemote.UserName = "NETWORK SERVICE" AndAlso _
(Right(processRemote.Name, Len(processToAttachTo)) = processToAttachTo) Then
If processRemote.IsBeingDebugged Then
MsgBox(processToAttachTo & " on " & machineName & " is already being debugged")
Else
processRemote.Attach2(dbgeng)
End If
attached = True
End If
Next
If Not attached Then
MsgBox(processToAttachTo & " is not running on " & machineName & ".")
End If
Catch ex As System.Exception
MsgBox("Exception attempting to attach to " & transportQualifier & ": " & ex.Message)
End Try
End Sub
Es posible que desee revisar gflags.exe . Una de sus opciones es un depurador para ejecutar adjunto a cada invocación de un ejecutable en particular.