"Присоединить к процессу" как событие после сборки

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

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

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

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

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

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

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

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

Я использую Visual Studio 2008 под Windows 7, 64 бит.

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

4 ответа

Решение

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

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 - Создайте свое приложение

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

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

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

vsjitdebugger.exe -p ProcessId 

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

Вот функция 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()
}

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

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
Другие вопросы по тегам