visual-studio 如何将调试器动态附加到特定进程

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1626458/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 11:09:11  来源:igfitidea点击:

How to attach a debugger dynamically to a specific process

visual-studiodebugging

提问by Jeff Cyr

I am building an internal development tool to manage different processes commonly used in our development environment. The tool shows the list of the monitored processes, indicating their running state and allows to start or stop each process.

我正在构建一个内部开发工具来管理我们开发环境中常用的不同流程。该工具显示受监控进程的列表,指示它们的运行状态并允许启动或停止每个进程。

I'd like to add the functionality of attaching a debugger to a monitored process from my tool instead of going in Debug-> Attach to processin Visual Studio and finding the process.

我想从我的工具中添加将调试器附加到受监控进程的功能,而不是进入调试->在 Visual Studio 中附加到进程并找到进程。

My goal is to have something like Debugger.Launch()that would show a list of the available Visual Studio. I can't use Debugger.Launch(), because it launches the debugger on the process that makes the call. I would need something like Debugger.Launch(processId).

我的目标是让类似的东西Debugger.Launch()显示可用的 Visual Studio 列表。我无法使用Debugger.Launch(),因为它会在进行调用的进程上启动调试器。我需要类似的东西Debugger.Launch(processId)

How do I achieve this functionality?

我如何实现这个功能?

A solution could be to implement a command in each monitored process to call Debugger.Launch()when the command is received from the monitoring tool, but I would prefer something that does not require to modify the code of the monitored processes.

一个解决方案可能是在每个受监控的进程中实现一个命令,以便Debugger.Launch()在从监控工具收到命令时调用,但我更喜欢不需要修改被监控进程代码的东西。

Side question:

侧面问题:

When using Debugger.Launch(), instances of Visual Studio that already have a debugger attached are not listed. Visual Studio is not limited to one attached debugger, you can attach on multiple process when using DebugAttach to process.

使用 时Debugger.Launch(),不会列出已附加调试器的 Visual Studio 实例。Visual Studio 不限于一个附加的调试器,您可以在使用DebugAttach to process时附加到多个进程

How do I bypass this limitation when using Debugger.Launch()or an alternative?

使用Debugger.Launch()或替代时如何绕过此限制?

回答by Jeff Cyr

A coworker ended up with a solution using DTE, and I posted the code on PasteBin.

一位同事最终得到了一个使用 DTE 的解决方案,我将代码发布在 PasteBin 上。

The methods of interest are AttachVisualStudioToProcessand TryGetVsInstance

感兴趣的方法是AttachVisualStudioToProcessTryGetVsInstance

Source Code

源代码

public static void AttachVisualStudioToProcess(Process visualStudioProcess, Process applicationProcess)
{
    _DTE visualStudioInstance;

    if (TryGetVsInstance(visualStudioProcess.Id, out visualStudioInstance))
    {
        //Find the process you want the Visual Studio instance to attach to...
        DTEProcess processToAttachTo = visualStudioInstance.Debugger.LocalProcesses.Cast<DTEProcess>().FirstOrDefault(process => process.ProcessID == applicationProcess.Id);

        // Attach to the process.
        if (processToAttachTo != null)
        {
            processToAttachTo.Attach();

            ShowWindow((int)visualStudioProcess.MainWindowHandle, 3);
            SetForegroundWindow(visualStudioProcess.MainWindowHandle);
        }
        else
        {
            throw new InvalidOperationException("Visual Studio process cannot find specified application '" + applicationProcess.Id + "'");
        }
    }
}

private static bool TryGetVsInstance(int processId, out _DTE instance)
{
    IntPtr numFetched = IntPtr.Zero;
    IRunningObjectTable runningObjectTable;
    IEnumMoniker monikerEnumerator;
    IMoniker[] monikers = new IMoniker[1];

    GetRunningObjectTable(0, out runningObjectTable);
    runningObjectTable.EnumRunning(out monikerEnumerator);
    monikerEnumerator.Reset();

    while (monikerEnumerator.Next(1, monikers, numFetched) == 0)
    {
        IBindCtx ctx;
        CreateBindCtx(0, out ctx);

        string runningObjectName;
        monikers[0].GetDisplayName(ctx, null, out runningObjectName);

        object runningObjectVal;
        runningObjectTable.GetObject(monikers[0], out runningObjectVal);

        if (runningObjectVal is _DTE && runningObjectName.StartsWith("!VisualStudio"))
        {
            int currentProcessId = int.Parse(runningObjectName.Split(':')[1]);

            if (currentProcessId == processId)
            {
                instance = (_DTE)runningObjectVal;
                return true;
            }
        }
    }

    instance = null;
    return false;
}

回答by u109919

WinDbg does the chain debugging for native code by default. If you want to launch another instance of Visual Studio, check Launch the Debugger Automaticallyon MSDN:

WinDbg 默认对本机代码进行链式调试。如果要启动 Visual Studio 的另一个实例,请选中MSDN 上的自动启动调试器

To automate the existing debugger, use Marshal.GetActiveObject to get the current EnvDTE.Debugger then let it attach to the process you just created.

要自动化现有的调试器,请使用 Marshal.GetActiveObject 获取当前的 EnvDTE.Debugger,然后让它附加到您刚刚创建的进程。

Sometimes, you may need to debug the startup code for an application that is launched by another process. Examples include services and custom setup actions. In these scenarios, you can have the debugger launch and automatically attach when your application starts.

To setup an application to launch the debugger automatically

  1. Start the Registry Editor (regedit).

  2. In the Registry Editor, open the HKEY_LOCAL_MACHINE folder.

  3. Navigate to HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\currentversion\image file execution options.

  4. In the Image File Execution Optionsfolder, locate the name of the application you want to debug, such as myapp.exe. If you cannot find the application you want to debug:

    a. Right-click the Image File Execution Optionsfolder, and on the shortcut menu, click New Key.

    b. Right-click the new key, and on the shortcut menu, click Rename.

    c. Edit the key name to the name of your application; myapp.exe, in this example.

  5. Right-click the myapp.exefolder, and on the shortcut menu, click New String Value.

  6. Right-click the new string value, and on the shortcut menu, click Rename.

  7. Change the name to debugger.

  8. Right-click the new string value, and on the shortcut menu, click Modify. The Edit Stringdialog box appears.

  9. In the Value databox, type vsjitdebugger.exe.

  10. Click OK.

  11. From the Registrymenu, click Exit.

  12. The directory containing vsjitdebugger.exe must be in your system path. To add it to the system path, follow these steps:

    a. Open the Control Panelin Classic view, and double-click System.

    b. Click Advanced System Settings.

    c. In System Properties, click the Advancedtab.

    d. On the Advancedtab, click Environment Variables.

    e. In the Environment Variablesdialog box, under System variables, select Path, then click the Editbutton.

    f. In the Edit System Variabledialog box, add the directory to the Variable valuebox. Use a semicolon to separate it from other entries in the list.

    g. Click OKto close the Edit System Variabledialog box.

    h. Click OKto close the Environment Variablesdialog box.

    i. Click OKto close the System Propertiesdialog box.

Now, use any method to start your application. Visual Studio will start and load the application.

有时,您可能需要调试由另一个进程启动的应用程序的启动代码。示例包括服务和自定义设置操作。在这些情况下,您可以启动调试器并在应用程序启动时自动附加。

设置应用程序以自动启动调试器

  1. 启动注册表编辑器 (regedit)。

  2. 在注册表编辑器中,打开 HKEY_LOCAL_MACHINE 文件夹。

  3. 导航到 HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\currentversion\image 文件执行选项。

  4. Image File Execution Options文件夹中,找到要调试的应用程序的名称,例如 myapp.exe。如果找不到要调试的应用程序:

    一个。右键单击Image File Execution Options文件夹,然后在快捷菜单上单击New Key

    湾 右键单击新键,然后在快捷菜单上单击重命名

    C。将密钥名称编辑为您的应用程序名称;myapp.exe,在本例中。

  5. 右键单击myapp.exe文件夹,然后在快捷菜单上单击“新建字符串值”

  6. 右键单击新字符串值,然后在快捷菜单上单击重命名

  7. 将名称更改为debugger.

  8. 右键单击新的字符串值,然后在快捷菜单上单击修改。该编辑字符串对话框出现。

  9. 数值数据框中,键入vsjitdebugger.exe

  10. 单击“确定”

  11. 注册表菜单中,单击退出

  12. 包含 vsjitdebugger.exe 的目录必须在您的系统路径中。要将其添加到系统路径,请按照下列步骤操作:

    一个。在经典视图中打开控制面板,然后双击系统

    湾 单击高级系统设置

    C。在系统属性中,单击高级选项卡。

    d. 在高级选项卡上,单击环境变量

    e. 在“环境变量”对话框中的“系统变量”下,选择“路径”,然后单击“编辑”按钮。

    F。在“编辑系统变量”对话框中,将目录添加到“变量值”框中。使用分号将其与列表中的其他条目分开。

    G。单击“确定”关闭“编辑系统变量”对话框。

    H。单击确定关闭环境变量对话框。

    一世。单击确定关闭系统属性对话框。

现在,使用任何方法启动您的应用程序。Visual Studio 将启动并加载应用程序。

回答by Vilas

Here is some information about how you can programmatically attach the debugger to multiple processes:

以下是有关如何以编程方式将调试器附加到多个进程的一些信息: