2013-01-07 8 views

Odpowiedz

11

Użyj uruchomiony obiekt stół, aby uzyskać wszystkie instancje, a następnie wybierz ten, który chcesz.

Nie sądzę, że można zrobić lepiej niż to. Jest to podobne do sposobu dołączania debuggera do instancji VS. Musisz wybrać jedną z listy.

IEnumerable<DTE> GetInstances() 
{ 
    IRunningObjectTable rot; 
    IEnumMoniker enumMoniker; 
    int retVal = GetRunningObjectTable(0, out rot); 

    if (retVal == 0) 
    { 
     rot.EnumRunning(out enumMoniker); 

     IntPtr fetched = IntPtr.Zero; 
     IMoniker[] moniker = new IMoniker[1]; 
     while (enumMoniker.Next(1, moniker, fetched) == 0) 
     { 
      IBindCtx bindCtx; 
      CreateBindCtx(0, out bindCtx); 
      string displayName; 
      moniker[0].GetDisplayName(bindCtx, null, out displayName); 
      Console.WriteLine("Display Name: {0}", displayName); 
      bool isVisualStudio = displayName.StartsWith("!VisualStudio"); 
      if (isVisualStudio) 
      { 
       object obj; 
       rot.GetObject(moniker[0], out obj); 
       var dte = obj as DTE; 
       yield return dte; 
      } 
     } 
    } 
} 

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

[DllImport("ole32.dll")] 
private static extern int GetRunningObjectTable(int reserved, out IRunningObjectTable prot); 
+0

Mam teraz wystarczająco dużo przedstawiciela, aby to skomentować, więc wysłałem odpowiedź z pytaniem, jakie były twoje wyciągi z użycia? Skopiowałem twój kod do mojego programu, mając nadzieję, że będę mógł użyć tej listy, aby uzyskać moją instancję VS, ale wiele słów kluczowych rzuca mi brakujące błędy przestrzeni nazw i jestem im obcy –

+0

@Matt Ferguson Używam tego kod tutaj: https://code.google.com/p/tray-service-control/source/browse/TrayServiceControl/Debugging/RunningObjectTable.cs –

+0

Ten kod nie jest tworzony. Mówi, że rot.GetObject wymaga dwóch parametrów. :? –

0

Poniżej znajduje się rozwiązanie dla VB.Net, aby uzyskać instancję CURRENT Visual Studio.

To, co robię, to proste porównywanie ciągów z procesami debugującymi przy użyciu nazwy bieżącego zestawu. Wydaje się, że działa zgodnie z oczekiwaniami, gdy wiele wystąpień VS są otwarte, próbowałem go w trybie debugowania i uwalniania, w Visual Studio 2013.

Import:

Imports System 
Imports System.Diagnostics.CodeAnalysis 
Imports System.Runtime.InteropServices 
Imports System.Runtime.InteropServices.ComTypes 
Imports EnvDTE80 

P/Wywołuje:

(NativeMethods.dll)

''' ---------------------------------------------------------------------------------------------------- 
''' <summary> 
''' Returns a pointer to an implementation of <see cref="IBindCtx"/> (a bind context object). 
''' <para></para> 
''' This object stores information about a particular moniker-binding operation. 
''' </summary> 
''' ---------------------------------------------------------------------------------------------------- 
''' <remarks> 
''' <see href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms678542%28v=vs.85%29.aspx"/> 
''' </remarks> 
''' ---------------------------------------------------------------------------------------------------- 
''' <param name="reserved"> 
''' This parameter is reserved and must be 0. 
''' </param> 
''' 
''' <param name="ppbc"> 
''' Address of an <see cref="IBindCtx"/> pointer variable that receives the 
''' interface pointer to the new bind context object. 
''' <para></para> 
''' When the function is successful, the caller is responsible for calling Release on the bind context. 
''' <para></para> 
''' A value of <see langword="Nothing"/> for the <paramref name="ppbc"/> value indicates that an error occurred. 
''' </param> 
''' ---------------------------------------------------------------------------------------------------- 
''' <returns> 
''' This function can return the standard return values <c>E_OUTOFMEMORY</c> and <c>S_OK</c>. 
''' </returns> 
''' ---------------------------------------------------------------------------------------------------- 
<SuppressMessage("Microsoft.Interoperability", "CA1401:PInvokesShouldNotBeVisible", justification:="Assembly Reference")> 
<DllImport("ole32.dll")> 
Public Shared Function CreateBindCtx(ByVal reserved As Integer, 
            ByRef ppbc As IBindCtx 
) As Integer 
End Function 

''' ---------------------------------------------------------------------------------------------------- 
''' <summary> 
''' Returns a pointer to the <see cref="IRunningObjectTable"/> interface on the local running object table (ROT). 
''' </summary> 
''' ---------------------------------------------------------------------------------------------------- 
''' <remarks> 
''' <see href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms684004%28v=vs.85%29.aspx"/> 
''' </remarks> 
''' ---------------------------------------------------------------------------------------------------- 
''' <param name="reserved"> 
''' This parameter is reserved and must be 0. 
''' </param> 
''' 
''' <param name="pprot"> 
''' The address of an <see cref="IRunningObjectTable"/> pointer variable that receives the 
''' interface pointer to the local ROT. 
''' <para></para> 
''' When the function is successful, the caller is responsible for calling Release on the interface pointer. 
''' <para></para> 
''' A value of <see langword="Nothing"/> for the <paramref name="pprot"/> value indicates that an error occurred. 
''' </param> 
''' ---------------------------------------------------------------------------------------------------- 
''' <returns> 
''' This function can return the standard return values <c>E_UNEXPECTED</c> and <c>S_OK</c>. 
''' </returns> 
''' ---------------------------------------------------------------------------------------------------- 
<SuppressMessage("Microsoft.Interoperability", "CA1401:PInvokesShouldNotBeVisible", justification:="Assembly Reference")> 
<DllImport("ole32.dll")> 
Public Shared Function GetRunningObjectTable(ByVal reserved As Integer, 
              ByRef pprot As IRunningObjectTable 
) As Integer 
End Function 

Reszta kodu:

''' ---------------------------------------------------------------------------------------------------- 
''' <summary> 
''' Gets a collection of the Visual Studio instances that are running on this PC. 
''' </summary> 
''' ---------------------------------------------------------------------------------------------------- 
''' <returns> 
''' An <see cref="IEnumerable(Of DTE2)"/> that contains the running Visual Studio instances, if any. 
''' </returns> 
''' ---------------------------------------------------------------------------------------------------- 
Public Shared Iterator Function GetVisualStudioInstances() As IEnumerable(Of DTE2) 

    Dim rot As IRunningObjectTable = Nothing 
    Dim enumMoniker As IEnumMoniker = Nothing 
    Dim retVal As Integer = NativeMethods.GetRunningObjectTable(0, rot) 

    If (retVal = 0) Then 

     rot.EnumRunning(enumMoniker) 

     Dim fetched As IntPtr = IntPtr.Zero 
     Dim moniker As IMoniker() = New IMoniker(0) {} 

     While (enumMoniker.Next(1, moniker, fetched) = 0) 

      Dim bindCtx As IBindCtx = Nothing 
      NativeMethods.CreateBindCtx(0, bindCtx) 

      Dim displayName As String = "" 
      moniker(0).GetDisplayName(bindCtx, Nothing, displayName) 

      If (displayName.StartsWith("!VisualStudio")) Then 
       Dim obj As New Object 
       rot.GetObject(moniker(0), obj) 
       Yield DirectCast(obj, DTE2) 
      End If 

     End While 

    End If 

End Function 

''' ---------------------------------------------------------------------------------------------------- 
''' <summary> 
''' Gets a <see cref="DTE2"/> object that represents the current Visual Studio instance that is running this project. 
''' </summary> 
''' ---------------------------------------------------------------------------------------------------- 
''' <returns> 
''' A <see cref="DTE2"/> object that represents the current Visual Studio instance that is running this project. 
''' </returns> 
''' ---------------------------------------------------------------------------------------------------- 
Public Shared Function GetCurrentVisualStudioInstance() As DTE2 

    Dim currentInstance As DTE2 = Nothing 
    Dim processName As String = Process.GetCurrentProcess.MainModule.FileName 
    Dim instances As IEnumerable(Of DTE2) = GetVisualStudioInstances 

    For Each instance As DTE2 In instances 

     For Each p As EnvDTE.Process In instance.Debugger.DebuggedProcesses 

      If (p.Name = processName) Then 
       currentInstance = instance 
       Exit For 
      End If 

     Next p 

    Next instance 

    Return currentInstance 

End Function 
Powiązane problemy