2009-08-13 81 views
4

我可以從VBScript中啓動一個新的隱藏Visual Studio的過程,並推動它編程,這樣做:以編程方式啓動Visual Studio; C#相當於VB的CreateObject的(「VisualStudio.DTE.8.0」)

Set DTE = CreateObject("VisualStudio.DTE.8.0") 
DTE.DoStuff() 

我怎麼做,在C#?

我已經試過:(編輯使用正確的類型,而不是一般的COM對象13759是VBScript代碼。)這樣的:

using EnvDTE; 
... 
DTE dte = new DTE(); 

但我得到「檢索COM類工廠組件與CLSID {3C9CFE1E-389F-4118-9FAD-365385190329}失敗「。

+0

我不確定這個..但爲什麼不是Process.Start(「devenv.exe」); ? – Galilyou 2009-08-13 07:00:22

+0

@ 7alwagy:「並以編程方式驅動它」 – RichieHindle 2009-08-13 07:05:51

回答

7

我找到了答案(感謝Sebastiaan Megens爲把我在正確的軌道上):

[STAThread] 
static void Main(string[] args) 
{ 
    System.Type t = System.Type.GetTypeFromProgID("VisualStudio.DTE.8.0", true); 
    DTE2 dte = (EnvDTE80.DTE2)System.Activator.CreateInstance(t, true); 

    // See http://msdn.microsoft.com/en-us/library/ms228772.aspx for the 
    // code for MessageFilter - just paste it in. 
    MessageFilter.Register(); 

    dte.DoStuff(); 
    dte.Quit(); 
} 

public class MessageFilter : IOleMessageFilter 
{ 
    ... Continues at http://msdn.microsoft.com/en-us/library/ms228772.aspx 

(與STAThread和的MessageFilter的廢話「,因爲對外部多線程應用程序和Visual Studio之間的爭用問題進行線程化「,無論如何,從http://msdn.microsoft.com/en-us/library/ms228772.aspx的代碼中粘貼它就可以工作。)

+1

啊,很酷的聽!有趣的是,我將來可能會需要它。 :) 問候, Sebastiaan – 2009-08-13 11:11:00

+0

只想添加,如果任何人有麻煩,那我沒有這個成功/微軟的'MessageFilter.Register()'調用,直到我把它** **前的'CreateInstance'調用。 – sorrell 2015-09-14 10:25:45

0

簡單的答案:寫在VB中,編譯它,用反射器打開它,並在C#模式下反編譯!

+0

不錯的主意,但VB代碼使用晚期綁定(即''DTE'只是一個通用的COM對象),我希望C#使用早期綁定。 – RichieHindle 2009-08-13 06:45:18

+0

而不是使用Reflector,爲什麼不直接查看Microsoft提供的源代碼? – AMissico 2009-09-02 13:13:33

3

我不知道如何啓動Visual Studio的新實例,但我通過調用使用現有的實例:

EnvDTE.DTE dte = (EnvDTE.DTE)System.Runtime.InteropServices.Marshal.GetActiveObject("VisualStudio.DTE.8.0"); 

可能創造一個新的實例類似的東西?希望這個對你有幫助。

問候,

Sebastiaan

+0

+1讓我走上了正確的軌道 - 爲您的代碼谷歌搜索導致我http://msdn.microsoft.com/en-us/library/68shb4dw%28VS.80%29.aspx它包含您的代碼連接到現有實例*和*創建一個新的代碼。 – RichieHindle 2009-08-13 07:53:03

2

用於VB的CreateObject的微軟源代碼。

<HostProtection(Resources:=HostProtectionResource.ExternalProcessMgmt)> _ 
    <SecurityPermissionAttribute(SecurityAction.Demand, Flags:=SecurityPermissionFlag.UnmanagedCode)> _ 
    Public Function CreateObject(ByVal ProgId As String, Optional ByVal ServerName As String = "") As Object 
     'Creates local or remote COM2 objects. Should not be used to create COM+ objects. 
     'Applications that need to be STA should set STA either on their Sub Main via STAThreadAttribute 
     'or through Thread.CurrentThread.ApartmentState - the VB runtime will not change this. 
     'DO NOT SET THREAD STATE - Thread.CurrentThread.ApartmentState = ApartmentState.STA 

     Dim t As Type 

     If ProgId.Length = 0 Then 
      Throw VbMakeException(vbErrors.CantCreateObject) 
     End If 

     If ServerName Is Nothing OrElse ServerName.Length = 0 Then 
      ServerName = Nothing 
     Else 
      'Does the ServerName match the MachineName? 
      If String.Compare(Environment.MachineName, ServerName, StringComparison.OrdinalIgnoreCase) = 0 Then 
       ServerName = Nothing 
      End If 
     End If 

     Try 
      If ServerName Is Nothing Then 
       t = Type.GetTypeFromProgID(ProgId) 
      Else 
       t = Type.GetTypeFromProgID(ProgId, ServerName, True) 
      End If 

      Return System.Activator.CreateInstance(t) 
     Catch e As COMException 
      If e.ErrorCode = &H800706BA Then 
       '&H800706BA = The RPC Server is unavailable 
       Throw VbMakeException(vbErrors.ServerNotFound) 
      Else 
       Throw VbMakeException(vbErrors.CantCreateObject) 
      End If 
     Catch ex As StackOverflowException 
      Throw ex 
     Catch ex As OutOfMemoryException 
      Throw ex 
     Catch ex As System.Threading.ThreadAbortException 
      Throw ex 
     Catch e As Exception 
      Throw VbMakeException(vbErrors.CantCreateObject) 
     End Try 
    End Function