“附加到进程”作为构建后事件

发布于 2024-09-26 06:29:56 字数 565 浏览 6 评论 0原文

我有一个在“w3wp.exe”进程下托管的应用程序。

在调试时,我经常发现自己遵循以下步骤:

1 - 进行一些更改

2 - 构建项目

3 - 使用“工具”菜单下的“附加到进程”对话框附加到“w3wp.exe”。

4 - 在应用程序中执行一些操作以使我的代码执行,这样我就可以在调试器中逐步执行它

我想在构建后脚本中自动执行步骤 3,以便 IDE 在构建后自动附加到进程已完成。请注意,我已经将应用程序作为构建后流程的一部分启动,因此我可以依靠此时现有的流程。

有谁知道如何自动执行“附加到进程”命令?来自命令行的东西会特别好,但宏也可以。

我在 Windows 7 64 位下使用 Visual Studio 2008。

编辑 @InSane 基本上给了我正确的答案,但它不起作用,因为我需要调试托管代码,而不是本机代码。看来 vsjitdebugger 默认为 Native 代码,因此我的断点没有被命中。从 IDE 内部,我可以指定“托管代码”,调试器将按预期附加。那么有没有办法让 vsjitdebugger 指向托管代码呢?

I have an application that runs hosted under the "w3wp.exe" process.

While debugging, I often find myself following these steps:

1 - Make some change

2 - Build the project

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

4 - Perform some action in the application to make my code execute, so I can step through it in the debugger

I'd like to automate step 3 in the post-build script, so that the IDE automatically attaches to the process after the build is completed. Note that I already launch the application as a part of the post-build process, so I can count on the process existing at this point.

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

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

Edit
@InSane basically gave me the right answer, but it does not work because I need to debug managed code, rather than native code. It seems that vsjitdebugger defaults to Native code, and thus my breakpoint is not hit. From inside the IDE, I can specify "managed code" and the debugger attaches as expected. So is there any way to point vsjitdebugger to managed code?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

把人绕傻吧 2024-10-03 06:29:56

我终于能够通过在互联网上其他地方找到的示例来解决这个问题。我在这里分享它,因为这对我很有帮助。

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 - 构建应用程序

I was finally able to solve this problem with an example I found elsewhere on the internet. I'm sharing it here since this was helpful to me.

1 - Create a new command line application with the below code (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 - Build your application

淡淡離愁欲言轉身 2024-10-03 06:29:56

您可以从 Windows 命令行尝试以下命令。

如果它按您的预期工作,您可以将其作为构建后步骤的一部分。

ProcessID 是您已启动且要附加到的进程的 ID。

vsjitdebugger.exe -p ProcessId 

从命令行使用它的其他选项包括:-
替代文本

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

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

ProcessID is the ID of the process you have launched that you want to attach to.

vsjitdebugger.exe -p ProcessId 

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

他是夢罘是命 2024-10-03 06:29:56

这是受 @JosephStyons 答案启发的 PowerShell 函数。适用于任何 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()
}

Here is a PowerShell function inspired by @JosephStyons's answer. Works with any VS version 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()
}
回眸一笑 2024-10-03 06:29:56

这是约瑟夫的改进版本。我添加了这个:
-不显示控制台(在项目的“应用程序”中将输出类型设置为“Windows 应用程序”。)
- 我将超时命令行参数设置为 0(为什么需要它?)
- 添加了第三个命令行 arg url,该命令行使用 Firefox 启动,但仅在站点首次在程序内部加载之后才启动。这是因为有些网站,尤其是 dotnetnuke,编译后需要很长时间才能加载。这样,只有在一切准备就绪后,Firefox 才会将您带入前台 Firefox 浏览器进行测试,在我的计算机上最多需要 1 分钟。同时你可以做其他事情。
附言。这个 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

Here is improved version of Joseph. I added this:
-dont show console (Set on your Project in "Application" the Output Type to "Windows Application".)
- i set timeout command line argument to 0 (why is it needed at all?)
- added third command line arg url, which is launched with firefox, but only after site is first loaded internally in program. this is because some sites, especially dotnetnuke, take long time to load after compile. so this way firefox will bring you into foreground firefox browser only after everything is ready to test, it takes up to 1 minute on my computer. you can work on something else in the mean time.
PS. this stackoverflow editor is a little dumb. thats why this text is not formatted pretty. if i add list bulletins code below doesnt show 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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文