我可以从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类工厂失败”。
答案 0 :(得分: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 :(得分:3)
我不知道如何启动Visual Studio的新实例,但我通过调用:
来使用现有实例EnvDTE.DTE dte = (EnvDTE.DTE)System.Runtime.InteropServices.Marshal.GetActiveObject("VisualStudio.DTE.8.0");
也许创建一个新实例是类似的?希望这有点帮助。
此致
Sebastiaan
答案 2 :(得分:2)
VBs 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
答案 3 :(得分:0)
简单回答:用VB编写,编译,用Reflector打开,用c#模式反编译!