2010-04-12 13 views
9

Tengo una biblioteca de clase administrada (digamos mylib.dll) y una aplicación administrada de un tercero (por ejemplo, app.exe) que está utilizando mylib.dll. Tengo el código de mylib.dll pero no de la app.exe. Actualmente, lo que hago es construir mylib.dll, copiarlo en el directorio de app.exe, iniciar app.exe y adjuntarlo al proceso. De esa forma si pongo puntos de interrupción en el código mylib.dll, los veo ser golpeados. ¿Pero de todos modos hay un corte automático en el código de mylib.dll cuando una aplicación externa llama a uno de sus métodos expuestos? es decir. Solo para los puntos de entrada de la dll.¿Hay alguna manera de entrar automáticamente en el depurador cuando se llaman a las funciones de mi biblioteca de clase?

gracias, Mishal

Respuesta

7

Bajo Proyecto -> Propiedades -> Depuración -> Acción de inicio se debe especificar la opción Iniciar programa externo e introduzca la ruta a su app.exe. Esto debería iniciar app.exe con el depurador adjunto.

Ver también How to: Change the Start Action for Application Debugging

Actualización: Los puntos de interrupción en Visual Studio están obligados ya sea a un lugar determinado (es decir, una línea específica de código en un archivo de origen) o un nombre de función. Por lo tanto, básicamente tiene dos opciones para interrumpir cualquier momento en que se llame a una función en su ensamblaje: O bien ponga puntos de interrupción en todas las declaraciones de función o en todos los nombres de función (Depurar -> Nuevo punto de interrupción -> Interrumpir nombre de función). Lamentablemente, la última opción requiere el nombre completo de la función y no permite comodines.

Otra alternativa que puede considerar es colocar Debug.Assert(false) al comienzo de todas las funciones de la biblioteca.

Otra opción más sería utilizar una macro de Visual Studio. La macro siguiente itera sobre su DOM código y añade un punto de interrupción a todos los métodos y propiedades públicas:

Option Strict Off 
Option Explicit Off 
Imports System 
Imports EnvDTE 
Imports EnvDTE80 
Imports EnvDTE90 
Imports System.Diagnostics 
Imports System.Windows.Forms 

Public Module Breakpoints 

    Sub AddBreakpointsToAllFunctionsAndProperties() 
     Try 
      If DTE.ActiveSolutionProjects.Length <> 1 Then 
       MsgBox("Select one project within the Solution Explorer, then re-run this macro.") 
       Exit Sub 
      End If 

      AddBreakpointsToProject(DTE.ActiveSolutionProjects(0)) 
     Catch ex As System.Exception 
      MessageBox.Show(ex.ToString) 
     End Try 
    End Sub 

    Private Sub AddBreakpointsToProject(ByVal proj As Project) 
     For i As Integer = 1 To proj.ProjectItems.Count 
      If Not proj.ProjectItems.Item(i).FileCodeModel Is Nothing Then 
       AddBreakpointsToProjectItems(proj.ProjectItems.Item(i).FileCodeModel.CodeElements) 
      End If 
     Next 
    End Sub 


    Private Sub AddBreakpointsToProjectItems(ByVal colCodeElements As CodeElements) 
     Dim objCodeElement As EnvDTE.CodeElement 

     If Not (colCodeElements Is Nothing) Then 
      For Each objCodeElement In colCodeElements 
       AddBreakpointsToProjectItem(objCodeElement) 
      Next 
     End If 
    End Sub 

    Private Sub AddBreakpointsToProjectItem(ByVal objCodeElement As CodeElement) 

     Dim objCodeNamespace As EnvDTE.CodeNamespace 
     Dim objCodeType As EnvDTE.CodeType 
     Dim objCodeFunction As EnvDTE.CodeFunction 
     Dim objCodeProperty As EnvDTE.CodeProperty 

     Try 
      'MessageBox.Show(objCodeElement.FullName & " (Kind: " & objCodeElement.Kind.ToString & ")") 

      If objCodeElement.Kind = vsCMElement.vsCMElementFunction Then 
       objCodeFunction = DirectCast(objCodeElement, EnvDTE.CodeFunction) 
       If objCodeFunction.Access = vsCMAccess.vsCMAccessPublic Then 
        DTE.Debugger.Breakpoints.Add(objCodeElement.FullName) 
       End If 
      ElseIf objCodeElement.Kind = vsCMElement.vsCMElementProperty Then 
       objCodeProperty = DirectCast(objCodeElement, EnvDTE.CodeProperty) 
       DTE.Debugger.Breakpoints.Add(objCodeElement.FullName) 
      End If 
     Catch ex As System.Exception 
      ' Ignore 
     End Try 

     If TypeOf objCodeElement Is EnvDTE.CodeNamespace Then 
      objCodeNamespace = CType(objCodeElement, EnvDTE.CodeNamespace) 
      AddBreakpointsToProjectItems(objCodeNamespace.Members) 
     ElseIf TypeOf objCodeElement Is EnvDTE.CodeType Then 
      objCodeType = CType(objCodeElement, EnvDTE.CodeType) 
      AddBreakpointsToProjectItems(objCodeType.Members) 
     ElseIf TypeOf objCodeElement Is EnvDTE.CodeFunction Then 
      objCodeFunction = DirectCast(objCodeElement, EnvDTE.CodeFunction) 
      AddBreakpointsToProjectItems(CType(objCodeElement, CodeFunction).Parameters) 
     End If 
    End Sub 

End Module 
+0

¿Qué versión de Visual Studio y para qué idioma es? – ChrisF

+0

Comprobado C# en VS 2008, pero si recuerdo correctamente, es muy similar o lo mismo en VS 2005 y para VB también. Tenga en cuenta que no es compatible con las ediciones Express. –

+0

Ok, sí, eso es información útil. Gracias. Pero mi pregunta real es que quiero que el depurador * automáticamente * se rompa (es decir, sin ningún punto de interrupción) en el depurador cuando app.exe llama a * any * el método de mylib.dll. Supongamos que mylib.dll puede tener muchas funciones de punto de entrada que podrían llamarse, por lo que poner puntos de corte manualmente en todos los métodos es un poco difícil :) – mishal153

3

No creo que no hay distancia para romper de forma automática en el código cada vez que se llama.

Los puntos de interrupción solo son válidos desde dentro del depurador, por lo que tendría que ejecutar todas las aplicaciones en el depurador de alguna manera.

¿Qué estás tratando de lograr con esto?

¿Desea saber cuándo se llama a su biblioteca? De ser así, solo agregue el registro a sus puntos de entrada.

Si tiene un problema específico con una aplicación específica, siga los consejos que le da 0xA3.

+0

Tengo el depurador conectado. Sí, solo estoy tratando de averiguar cuándo se llamará a mi biblioteca y qué métodos se están llamando. Registrar los puntos de entrada es una solución, que estoy haciendo ahora. Pero solo quería saber si hay alguna otra forma. Gracias por las respuestas – mishal153

5

no he probado en una biblioteca de clases, pero esto podría funcionar.

System.Diagnostics.Debugger.Break(); 
1

es también una opción.

Cuestiones relacionadas