以编程方式启动 Visual Studio; C# 相当于 VB 的 CreateObject(“VisualStudio.DTE.8.0”)

发布于 2024-08-02 04:33:28 字数 406 浏览 7 评论 0原文

我可以从 VBScript 启动一个新的隐藏 Visual Studio 进程,并以编程方式驱动它,方法如下:

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

How do I do that in C#? (编辑:使用正确的类型,而不是 VBScript 代码使用的通用 COM 对象。)

我已经尝试过:

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

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

I can start a new hidden Visual Studio process from VBScript, and drive it programmatically, by doing this:

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

How do I do that in C#? (Edit: using the correct types, not generic COM objects as used by that VBScript code.)

I've tried this:

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

but I get "Retrieving the COM class factory for component with CLSID {3C9CFE1E-389F-4118-9FAD-365385190329} failed".

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

送你一个梦 2024-08-09 04:33:28

我找到了答案(感谢 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 使其工作。)

I found the answer (thanks to Sebastiaan Megens for putting me on the right track):

[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

(The nonsense with STAThread and MessageFilter is "due to threading contention issues between external multi-threaded applications and Visual Studio", whatever that means. Pasting in the code from http://msdn.microsoft.com/en-us/library/ms228772.aspx makes it work.)

你与清晨阳光 2024-08-09 04:33:28

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

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

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

问候,

塞巴斯蒂安

I don't know how start a new instance of Visual Studio, but I use an existing instance by calling:

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

Maybe creating a new instance is something similar? Hope this helps a bit.

Regards,

Sebastiaan

我不是你的备胎 2024-08-09 04:33:28

Microsoft 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

Microsoft souce code for VB's 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
七婞 2024-08-09 04:33:28

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

Simple answer: write it in VB, compile it, open it with Reflector, and decompile it in c# mode!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文