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".
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.)
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
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
简单回答:在VB中编写,编译,用Reflector打开它,并在c#模式下反编译!
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.