Attach to process as post-build event

I have an application that is running the process "w3wp.exe".

In the debugging process, I often find myself as follows:

1 - Make some changes

2 - Create a project

3 - Attach to "w3wp.exe" using the "Attach to process" dialog in the "Tools" menu.

4 - Follow some steps in the application to execute my code, so I can execute it in the debugger

I would like to automate step 3 in a post-build script, so that the IDE automatically joins the process after the build is complete. Please note that I am already starting the application as part of the post-build process, so I can count on the currently existing process.

Does anyone know a way to automate the attach to process command? Something from the command line would be especially nice, but the macro would also do.

I am using Visual Studio 2008 under Windows 7, 64 bit.

Edit @InSane basically gave me the correct answer, but it doesn't work because I need to debug managed code, not native code. It seems that vsjitdebugger has its own code by default, and thus my breakpoint does not hit. From within the IDE, I can specify "managed code" and the debugger joins, as expected. So is there a way to point vsjitdebugger to managed code?

+6
visual-studio-2008 automation
source share
4 answers

Finally, I was able to solve this problem with an example that I found elsewhere on the Internet. I am sharing this because it was useful to me.

1 - Create a new command-line application with the code below (this example is in 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 - open the solution you want to debug in Visual Studio

3 - At the end of your post-build events, enter a call to this new utility, as in:

 c:\AutoAttach.exe w3wp.exe 20000 

4 - Create an application

+6
source share

You can try the following command from the Windows command prompt.

If it works as you expect, you can put it as part of the postbuild steps.

ProcessID is the identifier of the started process to which you want to connect.

 vsjitdebugger.exe -p ProcessId 

Other options for using this from the command line: alt text

+2
source share

Here is a PowerShell function inspired by @JosephStyons answer. Works with any version of VS without changes.

 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() } 
+1
source share

Here is an improved version of Joseph. I added: -dont show console (Set the output type to “Windows Application” in your application.) - I set the timeout command line argument to 0 (why is this necessary at all?) - the third arg command line URL is added url that is launched using firefox, but only after the site is first loaded inside the program. this is because some sites, especially dotnetnuke, take a long time to load after compilation. therefore, in this way firefox will bring you to the forefront of the firefox browser only after everything is ready for testing, it will take up to 1 minute on my computer. you can work on something else at the same time. PS. this stackoverflow editor is a little dumb. therefore this text is not formatted quite well. if I add the list list code below, it does not appear as 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
source share

All Articles