2010-10-05 29 views
6

J'ai une application qui s'exécute sous le processus "w3wp.exe"."Attach to Process" en tant qu'événement post-construction

Alors que le débogage, je me retrouve souvent, procédez comme suit:

1 - Faire un changement

2 - Construire le projet

3 - Rattacher à "w3wp.exe" en utilisant le « joindre traiter "dans le menu Outils.

4 - effectuer une action dans l'application pour faire exécuter mon code, je peux parcourir dans le débogueur

Je voudrais automatiser l'étape 3 dans le script de post-construction, de sorte que l'IDE s'attache automatiquement au processus une fois la construction terminée. Notez que je lance déjà l'application dans le cadre du processus de post-construction, donc je peux compter sur le processus existant à ce stade.

Est-ce que quelqu'un connaît un moyen d'automatiser la commande "attacher au processus"? Quelque chose de la ligne de commande serait particulièrement agréable, mais une macro ferait aussi. J'utilise Visual Studio 2008 sous Windows 7, 64 bits.

Modifier @InSane m'a donné essentiellement la bonne réponse, mais cela ne fonctionne pas parce que je dois déboguer le code managé, plutôt que du code natif. Il semble que vsjitdebugger utilise par défaut le code natif, et donc mon point d'arrêt n'est pas touché. De l'intérieur de l'EDI, je peux spécifier "code managé" et le débogueur s'attache comme prévu. Alors, est-il possible de pointer vsjitdebugger vers du code managé?

Répondre

6

J'ai enfin pu résoudre ce problème avec un exemple que je trouve ailleurs sur Internet. Je partage ici car cela m'a été utile.

1 - Créez une nouvelle application de ligne de commande avec le code ci-dessous (cet exemple est dans VB.NET).

Option Strict Off 
Option Explicit Off 
Imports System 
'On my machine, these EnvDTE* assemblies were here: 
'C:\Program Files (x86)\Common Files\microsoft shared\MSEnv\PublicAssemblies 
Imports EnvDTE 
Imports EnvDTE80 
Imports EnvDTE90 
Imports System.Diagnostics 
Imports System.Threading 

Module modMain 
    Function AttachToProcess(ByVal processName As String, _ 
          ByVal Timeout As Integer) As Boolean 
     Dim proc As EnvDTE.Process 
     Dim attached As Boolean 
     Dim DTE2 As EnvDTE80.DTE2 

     Try 
      DTE2 = _ 
      System.Runtime.InteropServices.Marshal.GetActiveObject("VisualStudio.DTE.9.0") 

      For Each proc In DTE2.Debugger.LocalProcesses 
       If (Right(proc.Name, Len(processName)).ToUpper = processName.ToUpper) Then 
        proc.Attach() 
        System.Threading.Thread.Sleep(Timeout) 
        attached = True 
       End If 
      Next 
     Catch Ex As Exception 
      Console.Write("Unable to Attach to Debugger : " & Ex.Message) 
     End Try 

     Return attached 
    End Function 

    Sub Main() 
     'to call w/ Command Line arguments follow this syntax 
     'AttachProcess <<ProcessName>> <<TimeOut>> 
     'AttachProcess app.exe 2000 
     Dim AppName As String = "w3wp.exe" 
     Dim TimeOut As Integer = 20000 '20 Seconds 
     Try 
      If Environment.GetCommandLineArgs().Length > 1 Then 
       AppName = Environment.GetCommandLineArgs(1) 
      End If 

      If Environment.GetCommandLineArgs().Length > 2 Then 
       If IsNumeric(Environment.GetCommandLineArgs(2)) Then 
        TimeOut = Environment.GetCommandLineArgs(2) 
       End If 
      End If 
      Environment.GetCommandLineArgs() 
      AttachToProcess(AppName, TimeOut) 
      Console.WriteLine("Attached!!") 

     Catch Ex As Exception 
      Console.Write("Unable to Attach to Debugger : " & Ex.Message) 
     End Try 
    End Sub 
End Module 

2 - Ouvrez la solution que vous voulez déboguer dans Visual Studio

3 - À la fin de vos événements "post-construction", entrez un appel à ce nouvel utilitaire, comme dans:

c:\AutoAttach.exe w3wp.exe 20000 

4 - Construire votre application

+2

nous devons mettre à jour la chaîne "VisualStudio.DTE.9.0" pour la version de studio visuel respective. Pour VisualStudio2012, ce sera "VisualStudio.DTE.11.0" – NavaRajan

+0

Pour Visual studio 2015, il sera "VisualStudio.DTE.14.0" – bluray

2

Vous pouvez essayer la commande suivante à partir de la ligne de commande Windows.

Si cela fonctionne comme prévu, vous pouvez le mettre dans le cadre de vos étapes de post-construction. ProcessID est l'ID du processus que vous avez lancé auquel vous voulez vous connecter.

vsjitdebugger.exe -p ProcessId 

Autres options pour l'utilisation de cette ligne de commande comprennent: - alt text

+0

Upvote pour une excellente suggestion, mais cela ne fonctionne pas tout à fait. Si j'utilise cette commande, elle me demande si je veux utiliser le débogueur actuel, ou en démarrer un nouveau. Je choisis l'actuel, et il pense assez dur pour un peu, mais tout point d'arrêt que j'ai défini arrive avec "Le point d'arrêt ne sera pas touché actuellement, aucun symbole n'a été chargé pour ce document." Si je choisis manuellement le même processus à partir de l'EDI, alors le point d'arrêt est configuré correctement. Des idées? – JosephStyons

+0

@JosephStyons - Je ne sais pas si cela fonctionnera mais est-il possible que vous deviez spécifier le dossier de symboles de débogage auparavant dans VS -> Options -> Débogage -> Symboles -> Emplacements des fichiers de symboles ->. Cela peut aider le débogueur à savoir où chercher les symboles ... – InSane

+0

même problème, je le fais avec un script PowerShell exécuté dans l'événement de post-construction et il me demande d'utiliser le debuger actuel ou un nouveau, mais le point de contact sont pas hissé. –

0

Voici version améliorée de Joseph. J'ai ajouté ceci: -dont show console (Définissez sur votre projet dans "Application" le type de sortie à "Application Windows". - J'ai mis l'argument de ligne de commande timeout à 0 (pourquoi est-ce nécessaire?) - ajouté la troisième ligne de commande arg url, qui est lancée avec firefox, mais seulement après que le site est chargé en interne dans le programme. C'est parce que certains sites, en particulier dotnetnuke, prennent beaucoup de temps à charger après la compilation. de cette façon, firefox vous amènera au premier plan navigateur Firefox seulement après que tout est prêt à tester, cela prend jusqu'à 1 minute sur mon ordinateur. vous pouvez travailler sur autre chose en attendant. PS. cet éditeur de stackoverflow est un peu bête. C'est pourquoi ce texte n'est pas formaté joli. si j'ajoute le code de liste de bulletins ci-dessous ne montre pas comme code.

Option Strict Off 
Option Explicit Off 
Imports System 
'On my machine, these EnvDTE* assemblies were here: 
'C:\Program Files (x86)\Common Files\microsoft shared\MSEnv\PublicAssemblies 
Imports EnvDTE 
Imports EnvDTE80 
Imports EnvDTE90 
Imports System.Diagnostics 
Imports System.Threading 
Imports System.Collections.Generic 
Imports System.Linq 
Imports System.Text 
Imports System.Net 

Module modMain 
    Function AttachToProcess(ByVal processName As String, _ 
          ByVal Timeout As Integer) As Boolean 
     Dim proc As EnvDTE.Process 
     Dim attached As Boolean 
     Dim DTE2 As EnvDTE80.DTE2 

     Try 
      DTE2 = _ 
      System.Runtime.InteropServices.Marshal.GetActiveObject("VisualStudio.DTE.11.0") 

      For Each proc In DTE2.Debugger.LocalProcesses 
       If (Right(proc.Name, Len(processName)).ToUpper = processName.ToUpper) Then 
        proc.Attach() 
        System.Threading.Thread.Sleep(Timeout) 
        attached = True 
        Exit For 
       End If 
      Next 
     Catch Ex As Exception 
      Console.Write("Unable to Attach to Debugger : " & Ex.Message) 
     End Try 

     Return attached 
    End Function 

    Sub Main() 
     'to call w/ Command Line arguments follow this syntax 
     'AttachProcess <<ProcessName>> <<TimeOut>> 
     'AttachProcess app.exe 2000 
     Dim AppName As String = "w3wp.exe" 
     Dim TimeOut As Integer = 20000 '20 Seconds 
     Dim Url As String = "http://www.dnndev.me/" 
     Try 
      If Environment.GetCommandLineArgs().Length > 1 Then 
       AppName = Environment.GetCommandLineArgs(1) 
      End If 

      If Environment.GetCommandLineArgs().Length > 2 Then 
       If IsNumeric(Environment.GetCommandLineArgs(2)) Then 
        TimeOut = Environment.GetCommandLineArgs(2) 
       End If 
      End If 

      If Environment.GetCommandLineArgs().Length > 3 Then 
       Url = Environment.GetCommandLineArgs(3) 
      End If 

      Environment.GetCommandLineArgs() 
      AttachToProcess(AppName, TimeOut) 
      'Console.WriteLine("Attached!!") 

      'load site for faster opening later 
      Using client = New WebClient() 
       Dim contents = client.DownloadString(Url) 
      End Using 

      'open site in firefox 
      Dim ExternalProcess As New System.Diagnostics.Process() 
      ExternalProcess.StartInfo.FileName = "c:\\Program Files (x86)\\Mozilla Firefox\\firefox.exe" 
      ExternalProcess.StartInfo.WindowStyle = ProcessWindowStyle.Minimized 
      ExternalProcess.StartInfo.Arguments = "-url " & Url 
      ExternalProcess.Start() 
      'ExternalProcess.WaitForExit() 

     Catch Ex As Exception 
      Console.Write("Unable to Attach to Debugger : " & Ex.Message) 
     End Try 
    End Sub 
End Module 
+0

Cela ne fonctionne pas de moi. En utilisant VS2015, cela pourrait-il être la raison? Fondamentalement, utilisez les événements de construction pour exécuter un programme, puis ce programme à "attacher". J'ai ajouté un BP à mon projet principal mais il n'est pas touché. Je peux le faire manuellement sans problème. – AbstractDissonance

1

Voici une fonction PowerShell inspirée de la réponse @ JosephStyons. Fonctionne avec n'importe quelle version VS sans modifications.

function Debug-ProcessVS([int] $processId) 
{ 
    $vsProcess = Get-Process devenv | Select-Object -First 1 
    if (!$vsProcess) {throw "Visual Studio is not running"} 
    $vsMajorVersion = $vsProcess.FileVersion -replace '^(\d+).*', '$1' 
    $dte = [System.Runtime.InteropServices.Marshal]::GetActiveObject("VisualStudio.DTE.$vsMajorVersion.0") 
    $debugee = $dte.Debugger.LocalProcesses | ? {$_.ProcessID -eq $processId} 
    if (!$debugee) {throw "Process with ID $processId does not exist."} 
    $debugee.Attach() 
}