7
votes

"Joindre au processus" en tant qu'événement post-construction

J'ai une application qui s'exécute hébergée dans le processus "W3WP.EXE".

Tout en débogage, je me trouve souvent en suivant ces étapes:

1 - Faites du changement

2 - Construisez le projet

3 - Attachez-la à "W3WP.exe" à l'aide de la boîte de dialogue "Joindre à Process" dans le menu Outils.

4 - Effectuer une certaine action dans l'application pour que mon code soit exécuté, je peux donc passer à travers elle dans le débogueur

J'aimerais automatiser l'étape 3 dans le script post-Build, de sorte que l'IDE attache automatiquement au processus après la fin de la construction. Notez que je lance déjà l'application dans le cadre du processus post-build, je peux donc compter sur le processus existant à ce stade.

Est-ce que quelqu'un connaît un moyen d'automatiser la commande "Joindre à Process"? Quelque chose de la ligne de commande serait particulièrement gentil, mais une macro aurait aussi une macro.

J'utilise Visual Studio 2008 sous Windows 7, 64 bits.

edit @Insane m'a essentiellement donné la bonne réponse, mais cela ne fonctionne pas car j'ai besoin de déboguer du code géré, plutôt que du code natif. Il semble que Vsjitdebugger par défaut le code natif et que mon point d'arrêt n'est donc pas touché. De l'intérieur de l'IDE, je peux spécifier "code géré" et le débogueur attache comme prévu. Il y a donc un moyen de pointer vsjitdebugger au code géré?


0 commentaires

4 Réponses :


2
votes

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

Si vous y travaillez, vous pouvez le mettre dans le cadre de vos étapes de PostBuild.

processID est l'ID du processus. Vous avez lancé que vous souhaitez attacher à. xxx

Autres options d'utilisation de la ligne de commande incluent: - texte alt


3 commentaires

Upvote pour une bonne suggestion, mais cela ne fonctionne pas bien. Si j'utilise cette commande, il me demande si je veux utiliser le débogueur actuel ou en commencer une nouvelle. Je choisis le courant actuel, et il pense assez difficile pour un peu, mais que tout point de rupture que j'ai défini montait de "Le point d'arrêt ne sera pas actuellement touché. Aucun symbole n'a été chargé pour ce document." Si je choisis manuellement le même processus à partir de l'IDE, le point d'arrêt s'installe correctement. Des idées?


@Josephstyons - Je ne suis pas sûr que cela fonctionnera, mais il vous est possible que vous devez spécifier le dossier de symboles de débogage à l'avance dans VS -> Options -> Débogage -> Symboles -> Symboles Lieux de fichiers -> . Cela peut aider le débogueur savoir où chercher les symboles ...


Même problème, je fais avec un script PowerShell exécuté dans l'événement Post Build et il me demande d'utiliser le débuteur actuel ou un nouveau, mais le point de vie ne correspond pas au point de vie.



7
votes

J'ai finalement pu résoudre ce problème avec un exemple que j'ai trouvé ailleurs sur Internet. Je le partage ici depuis que 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). P>

c:\AutoAttach.exe w3wp.exe 20000


2 commentaires

Nous devons mettre à jour la chaîne "VisualStudio.DTE.9.0" pour la version Visual Studio correspondante. Pour VisualStudio2012, ce sera "VisualStudio.DTE.11.0"


Pour Visual Studio 2015, ce sera "VisualStudio.DTE.14.0"



0
votes

Voici une version améliorée de Joseph. J'ai ajouté ceci: -Dont Afficher la console (définie sur votre projet dans "Application" Type de sortie à "Application Windows".) - Je définis l'argument de ligne de commande timeout à 0 (pourquoi est-il nécessaire du tout?) - Ajout de la troisième ligne de commande ARG URL, qui est lancée avec Firefox, mais uniquement après que le site est chargé d'abord en interne dans le programme. En effet, certains sites, en particulier DotNetNuke, prennent beaucoup de temps à charger après la compilation. De sorte que cette façon Firefox vous apportera un navigateur Firefox avant-plan uniquement après que tout soit prêt à tester, il prend jusqu'à 1 minute sur mon ordinateur. Vous pouvez travailler sur autre chose dans le temps moyen. Ps. Cet éditeur Stackoverflow est un peu muet. C'est pourquoi ce texte n'est pas joli formaté. Si j'ajoute que la liste des bulletins de liste 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


1 commentaires

Cela ne fonctionne pas me former. Utiliser VS2015, cela pourrait-il être la raison? Utilisez fondamentalement les événements de construction pour exécuter un programme, ce programme pour «attacher». J'ai ajouté un BP à mon projet principal mais ce n'est pas touché. Je peux le faire manuellement sans problème.



1
votes

Voici une fonction PowerShell inspirée de la réponse de @ 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()
}


0 commentaires