"Присоединить к процессу" как событие после сборки
У меня есть приложение, которое запускается в процессе "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