4

我可以从 VBScript 启动一个新的隐藏 Visual Studio 进程,并通过执行以下操作以编程方式驱动它:

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

我如何在 C# 中做到这一点?(编辑:使用正确的类型,而不是该 VBScript 代码使用的通用 COM 对象。)

我试过这个:

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

但我得到“检索具有 CLSID {3C9CFE1E-389F-4118-9FAD-365385190329} 的组件的 COM 类工厂失败”。

4

4 回答 4

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使它工作。)

于 2009-08-13T07:50:53.903 回答
3

我不知道如何启动 Visual Studio 的新实例,但我通过调用来使用现有实例:

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

也许创建一个新实例是类似的?希望这个对你有帮助。

问候,

塞巴斯蒂安

于 2009-08-13T07:19:54.653 回答
2

VB 的 CreateObject 的 Microsoft 源代码。

    <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
于 2009-09-02T13:13:38.000 回答
0

简单回答:用VB写,编译,用Reflector打开,c#模式反编译!

于 2009-08-13T06:34:38.440 回答