Laufende Visual Studio Instanz filtern
Frank Dzaebel, erstellt am:
4.04.2007, zuletzt geändert: 9.04.2007
Kategorie:Implementation, .NET-Version:2.0,
Das Problem, dass ein
GetActiveObject("VisualStudio.DTE") nur die zuerst erstellte (registrierte)
Visual Studio Instanz darstellt, kann man durch eine Durchsuchung des ROT (Running
Object Table), nach einer Instanz, dessen Prozess-ID am Ende des "runningObjectName"
steht und dessen ProgID vorneweg steht, lösen.
Getestet auf [Visual Studio 2005,
Visual Studio Codename Orcas März
CTP 2007]
Weiterführende Literatur:
Automating a specific instance of Visual Studio .NET using C#
Get running Visual Studio instances and corresponding _DTE objects
using System;
using System.Runtime.InteropServices.ComTypes;
using System.Runtime.InteropServices;
using System.Diagnostics;
class VStudio
{
[DllImport("ole32.dll")]
static extern int GetRunningObjectTable(int reserved, out IRunningObjectTable prot);
[DllImport("ole32.dll")]
static extern int CreateBindCtx(int reserved, out IBindCtx ppbc);
/// <summary>Rückgabe: Die Instanz des aktuellen Prozesses aller laufenden Instanzen
/// der ProgID, die momentan im Running Object Table (ROT) sind. </summary>
static object ROT_Instanz(string progID)
{
IntPtr numFetched = IntPtr.Zero;
IRunningObjectTable runningObjectTable;
IEnumMoniker monikerEnumerator;
IMoniker[] monikers = new IMoniker[1];
GetRunningObjectTable(0, out runningObjectTable);
runningObjectTable.EnumRunning(out monikerEnumerator);
monikerEnumerator.Reset(); string progIDValue = "!" + progID;
while (monikerEnumerator.Next(1, monikers, numFetched) == 0)
{
IBindCtx ctx; CreateBindCtx(0, out ctx);
string runningObjectName;
monikers[0].GetDisplayName(ctx, null, out runningObjectName);
if (!runningObjectName.StartsWith(progIDValue)) continue;
string procID = ":"+Process.GetCurrentProcess().Id.ToString();
object runningObjectVal;
if (!runningObjectName.EndsWith(procID)) continue;
runningObjectTable.GetObject(monikers[0], out runningObjectVal);
return runningObjectVal;
}
return null;
}
/// <summary>Visual-Studio-Instanz (EnvDTE.DTE).</summary>
static public EnvDTE.DTE Instanz()
{
return ROT_Instanz("VisualStudio.DTE") as EnvDTE.DTE;
}
}
Aufruf (z.B.) in einem UserControl zur Designzeit:
EnvDTE.DTE dte = VStudio.Instanz();
MessageBox.Show(dte.ActiveDocument.FullName);