«Присоединить к процессу» как событие после сборки - PullRequest
6 голосов
/ 05 октября 2010

У меня есть приложение, которое запускается в процессе "w3wp.exe".

Во время отладки я часто выполняю следующие действия:

1 - внести некоторые изменения

2 - Построить проект

3 - Присоединить к «w3wp.exe» с помощью диалога «присоединить к процессу» в меню «Инструменты».

4 - выполнить какое-либо действие в приложении, чтобы мой код выполнялся, чтобы я мог выполнить его в отладчике

Я бы хотел автоматизировать шаг 3 в сценарии после сборки, чтобы среда IDE автоматически подключалась к процессу после завершения сборки. Обратите внимание, что я уже запускаю приложение как часть процесса после сборки, поэтому могу рассчитывать на процесс, существующий на данный момент.

Кто-нибудь знает способ автоматизации команды «присоединить к процессу»? Что-то из командной строки было бы особенно хорошо, но макрос тоже подойдет.

Я использую Visual Studio 2008 под Windows 7, 64-разрядная версия.

Редактировать @InSane в основном дал мне правильный ответ, но он не работает, потому что мне нужно отлаживать управляемый код, а не собственный код. Похоже, что vsjitdebugger по умолчанию использует нативный код, и поэтому моя точка останова не достигнута. Внутри IDE я могу указать «управляемый код», и отладчик подключается, как и ожидалось. Так есть ли способ указать vsjitdebugger на управляемый код?

Ответы [ 4 ]

7 голосов
/ 21 декабря 2010

Я наконец смог решить эту проблему с примером, который я нашел в Интернете. Я делюсь этим здесь, так как это было полезно для меня.

1 - Создайте новое приложение командной строки с приведенным ниже кодом (этот пример в 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 - Откройте решение, которое вы хотите отладить в Visual Studio

3 - В конце ваших событий после сборки введите вызов этой новой утилиты, как в:

c:\AutoAttach.exe w3wp.exe 20000

4 - Создайте приложение

2 голосов
/ 05 октября 2010

Вы можете попробовать следующую команду из командной строки Windows.

Если она работает так, как вы ожидаете, вы можете поместить ее как часть ваших шагов после сборки.

Идентификатор процесса - это идентификаторпроцесс, который вы запустили и к которому хотите присоединиться.

vsjitdebugger.exe -p ProcessId 

Другие варианты использования этого из командной строки: - alt text

1 голос
/ 15 сентября 2017

Вот функция PowerShell, вдохновленная ответом @ JosephStyons. Работает с любой версией VS без изменений.

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 голосов
/ 23 января 2015

Вот улучшенная версия Джозефа. Я добавил это: -не показывать консоль (установите для своего проекта в «Приложении» тип вывода «Приложение Windows».) - я установил аргумент командной строки тайм-аута на 0 (зачем он вообще нужен?) - добавлен третий аргумент командной строки arg url, который запускается с помощью firefox, но только после первой загрузки сайта внутри программы. Это связано с тем, что некоторые сайты, особенно dotnetnuke, долго загружаются после компиляции. Таким образом, Firefox выведет вас на передний план браузера Firefox только после того, как все будет готово к тестированию, на моем компьютере это займет до 1 минуты. тем временем вы можете работать над чем-то другим. PS. этот редактор stackoverflow немного тупой. вот почему этот текст не отформатирован довольно. если я добавлю список бюллетеней, код ниже не будет отображаться как код.

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
...