views:

68

answers:

1

I have a WinForms Application (.net 3.5) which displays a list of processes.

I would like to be able to attach to one of those processes. I have multiple Visual Studio 2010 instances running and I would like to create a List/Dropdown where I select one of those instances and then attach the Debugger to it.

Getting the VS2010 instances shouldn't be too hard, but I have no idea how to invoke the "attach to process" command. I want to avoid SendKeys-Type solutions, so I just wonder if there is some way to do that?

edit: To clarify: I want to use a specific running VS2010 to debug an external application.

+3  A: 

One approach is to use EnvDTE which is the COM automation interface for Visual Studio:

http://msdn.microsoft.com/en-us/library/envdte(VS.100).aspx

You can get at automation interfaces for running instances of Visual Studio by fishing around in the Running Objects Table (ROT). Once you have an instance of the interface you can then automate a selected instance of Visual Studio to attach to a process you desire.

Below is a basic example of how to do this. You will need to add a reference to your project to EnvDTE. This assembly is at the following location on my machine:

C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\PublicAssemblies\EnvDTE.dll

Updated

Updated to give example of getting Visual Studio instance automation interface by process ID.

using System;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using EnvDTE;

namespace VS2010EnvDte
{
internal class Program
{
    [DllImport("ole32.dll")]
    public static extern int GetRunningObjectTable(int reserved, out IRunningObjectTable prot);

    [DllImport("ole32.dll")]
    public static extern int CreateBindCtx(int reserved, out IBindCtx ppbc);

    private static void Main()
    {
        //ProcessId of the VS instance - hard-coded here.
        int visualStudioProcessId = 5520;

        _DTE visualStudioInstance;

        if (TryGetVSInstance(visualStudioProcessId, out visualStudioInstance))
        {
            Process processToAttachTo = null;

            //Find the process you want the VS instance to attach to...
            foreach (Process process in visualStudioInstance.Debugger.LocalProcesses)
            {
                if (process.Name == @"C:\Users\chibacity\AppData\Local\Google\Chrome\Application\chrome.exe")
                {
                    processToAttachTo = process;
                    break;
                }
            }

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

    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;
    }
}
}
chibacity
@Michael I have not used this technique since VS2005, and although I coded this up against 2010 and tested it, did you try it and come up against issues that might be helpful? I will be introducing a feature in my application in the near future that relies on this approach and wondered if there were any 2010 got-yas you came across. Thanks.
chibacity