2009-08-13 60 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