How to attach a debugger dynamically to a specific

2019-01-31 10:15发布

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 process in Visual Studio and finding the process.

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).

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.

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.

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

3条回答
Anthone
2楼-- · 2019-01-31 10:27

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

The methods of interest are AttachVisualStudioToProcess and TryGetVsInstance

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;
}
查看更多
放我归山
3楼-- · 2019-01-31 10:31

WinDbg does the chain debugging for native code by default. If you want to launch another instance of Visual Studio, check Launch the Debugger Automatically on 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.

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 Options folder, 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 Options folder, 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.exe folder, 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 String dialog box appears.

  9. In the Value data box, type vsjitdebugger.exe.

  10. Click OK.

  11. From the Registry menu, 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 Panel in Classic view, and double-click System.

    b. Click Advanced System Settings.

    c. In System Properties, click the Advanced tab.

    d. On the Advanced tab, click Environment Variables.

    e. In the Environment Variables dialog box, under System variables, select Path, then click the Edit button.

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

    g. Click OK to close the Edit System Variable dialog box.

    h. Click OK to close the Environment Variables dialog box.

    i. Click OK to close the System Properties dialog box.

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

查看更多
萌系小妹纸
4楼-- · 2019-01-31 10:50

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

查看更多
登录 后发表回答