I am currently building software factories and I needed a way to have a list of running Visual Studio instances and the corresponding EnvDTE._DTE object to manipulate the solution. Windows internally keeps a list of COM objects that are currently running, called the Running Object Table (ROT). VS .NET 2005 for example, register itself in the ROT as "!VisualStudio.DTE.8.0:pid" where 'pid' is the process id of the corresponding VS 2005 instance.
DTEHelper.cs -
Copy Codeusing System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using EnvDTE;
public static class DTEHelper
{
const uint S_OK = 0;
[DllImport("ole32.dll")]
public static extern uint GetRunningObjectTable(uint reserved, out IRunningObjectTable ROT);
[DllImport("ole32.dll")]
public static extern uint CreateBindCtx(uint reserved, out IBindCtx ctx);
static IDictionary<string, object> GetRunningObjectTable()
{
IDictionary<string, object> rotTable = new Dictionary<string, object>();
IRunningObjectTable runningObjectTable;
IEnumMoniker monikerEnumerator;
IMoniker[] monikers = new IMoniker[1];
GetRunningObjectTable(0, out runningObjectTable);
runningObjectTable.EnumRunning(out monikerEnumerator);
monikerEnumerator.Reset();
IntPtr numberFetched = IntPtr.Zero;
while (monikerEnumerator.Next(1, monikers, numberFetched) == 0)
{
IBindCtx ctx;
CreateBindCtx(0, out ctx);
string runningObjectName;
monikers[0].GetDisplayName(ctx, null, out runningObjectName);
Marshal.ReleaseComObject(ctx);
object runningObjectValue;
runningObjectTable.GetObject(monikers[0], out runningObjectValue);
if (!rotTable.ContainsKey(runningObjectName))
rotTable.Add(runningObjectName, runningObjectValue);
}
return rotTable;
}
public static IDictionary<string, _DTE> GetRunningVSIDETable()
{
IDictionary<string, object> runningObjects = GetRunningObjectTable();
IDictionary<string, _DTE> runningDTEObjects = new Dictionary<string, _DTE>();
foreach (string objectName in runningObjects.Keys)
{
if (!objectName.StartsWith("!VisualStudio.DTE"))
continue;
_DTE ide = runningObjects[objectName] as _DTE;
if (ide == null)
continue;
runningDTEObjects.Add(objectName, ide);
}
return runningDTEObjects;
}
}