Atachar procesos automáticamente con macros de Visual Studio

16 07 2008

La manera de atachar un proceso a Visual Studio es clasicamente mediante ‘Debug – Attach to process’ o el más productivo Ctrl + Alt + P, y luego seleccionar el o los procesos que querramos depurar.

En desarrollos medianamente importantes es muy probable que debamos realizar este procedimiento repetidas veces para depurar un proyecto fuera de la interface de usuario, expuesto mediante una capa de servicios, llámese WS, remoting, WCF, etc. Ni hablar del worker process de ASP.NET,  ‘aspnet_wp.exe’. También es común que corramos un proyecto desde fuera del Visual Studio para evitar la compilación, y luego lo atachemos al IDE.

Entonces, si los procesos que atachamos son siempre los mismos, ¿por que no automatizar la tarea?, bueno, la solución que propongo es una macro de Visual Studio que haga este trabajo, atachando con un atajo de teclado todos los procesos que sean necesarios.

Para incluirla en VS, vamos al editor de macros (Alt + F11), agregamos un nuevo módulo y reemplazamos el contenido por el siguiente:

Imports System.Collections.Generic
Imports EnvDTE
Imports EnvDTE80
Imports System.Text

Public Module DebugMacros

    Private Enum EnumAction
        ResultOK
        ReRunWithDisatach
        Abort
    End Enum

    Public Sub AttachProcs()
        Dim ProcessList As New List(Of String)
        ProcessList.Add("InterfaceUsuario.exe")
        ProcessList.Add("MiServiceLayer.exe")
        AttachProcs(False, ProcessList)
    End Sub

    Private Sub AttachProcs(ByVal detachAll As Boolean, ByVal ProcessList As List(Of String))

        If detachAll Then DTE.Debugger.DetachAll()

        Dim isOK As EnumAction = EnumAction.ResultOK
        Dim sbErrorResult As New StringBuilder

        For Each proc As String In ProcessList
            Dim match As Boolean = False
            For i As Integer = 1 To DTE.Debugger.LocalProcesses.Count
                If DTE.Debugger.LocalProcesses.Item(i).Name.EndsWith(proc) Then
                    match = True
                    Exit For
                End If
            Next
            If Not match Then
                sbErrorResult.Append("El proceso '" + proc + "' no se está ejecutando." + vbCrLf)
                isOK = EnumAction.Abort
            End If
        Next

        If isOK = EnumAction.ResultOK Then
            'Desatacho todos los procesos
            Dim dbg2 As EnvDTE80.Debugger2 = DTE.Debugger
            Dim trans As EnvDTE80.Transport = dbg2.Transports.Item("Default")
            Dim dbgeng(1) As EnvDTE80.Engine
            dbgeng(0) = trans.Engines.Item("Managed")
            Dim proc2 As EnvDTE80.Process2
            For Each processName As String In ProcessList
                Try
                    proc2 = dbg2.GetProcesses(trans, ".").Item(processName)
                    proc2.Attach2(dbgeng)
                Catch ex As Exception
                    If ex.Message.EndsWith("8971001E") Then
                        sbErrorResult.Append("Error atachando " + processName + ". " + "El proceso ya se encuentra atachado" + vbCrLf)
                        isOK = EnumAction.ReRunWithDisatach
                    Else
                        sbErrorResult.Append("Error inesperado atachando " + processName + ". " + ex.Message + vbCrLf)
                        isOK = EnumAction.Abort
                    End If
                End Try
            Next
        Else
        End If

        Select Case isOK
            Case EnumAction.Abort
                DTE.Debugger.DetachAll()
                MsgBox(sbErrorResult.ToString + vbCrLf + "No se ha atachado ningún proceso", MsgBoxStyle.OkOnly, "Error al atachar proceso")
            Case EnumAction.ReRunWithDisatach
                If MsgBox("Hay procesos previamente atachados. ¿Desea reatacharlos?", _
                                    MsgBoxStyle.YesNo, "Atachar Proceso") = MsgBoxResult.Yes Then
                    AttachProcs(True, ProcessList)
                    Exit Sub
                End If
            Case EnumAction.ResultOK
                Dim Resultado As New StringBuilder
                For Each s As String In ProcessList
                    Resultado.Append(s + vbCrLf)
                Next
                MsgBox("Se han atachado los siguientes procesos: " + vbCrLf + Resultado.ToString, MsgBoxStyle.OkOnly, "Proceso atachados")
        End Select
    End Sub

End Module

Observar que en AttachProcs() hay una colección con los nombres de los procesos la cual hay que editar de acuerdo a nuestras necesidades.

Ahora solo falta asignarle una combinación de teclas, desde Tools – Options – Keyboard, filtramos por “Macro” o “AtachProcs” y una vez ubicada la macro le asignamos una combinación de teclas.

Ahora solo basta correr los procesos por fuera de Visual Studio y atacharlos con la combinación de teclas.

Si el código encuentra alguno de los procesos atachado, desatacha todos los procesos e intenta nuevamente.

Nota: Este simple código está hecho a partir de la grabadora de macros (Tools – Macros – Record Temporary Macro), recordemos que todo lo que hacemos en VS queda registrado en la grabadora y que casi todo en el entorno es un objeto que se puede manipular.

Anuncios

Acciones

Information

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s




A %d blogueros les gusta esto: