Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I am creating a project automation tool in Visual Studio 2013 where I have my own project template and I am trying to add it to an existing solution programatically.I am using the following code in a console application.

EnvDTE.DTE dte = (EnvDTE.DTE)Marshal.GetActiveObject("VisualStudio.DTE.12.0");
string solDir = dte.Solution.FullName;
solDir=solDir.Substring(0, solDir.LastIndexOf(""));
dte.Solution.AddFromTemplate(path, solDir+"\TestProj", "TestProj", false);

It is working when I run the application from Visual Studio IDE. But when I try to run the exe from command prompt, I get the following exception.

Unhandled Exception: System.Runtime.InteropServices.COMException: Operation unav
ailable (Exception from HRESULT: 0x800401E3 (MK_E_UNAVAILABLE))
at System.Runtime.InteropServices.Marshal.GetActiveObject(Guid& rclsid, IntPtr reserved, Object&   ppunk)
at System.Runtime.InteropServices.Marshal.GetActiveObject(String progID)
at ProjectAutomation.Console.Program.Main(String[] args) 

I want to know whether there is any way to get the active EnvDTE.DTE instance outside Visual Studio IDE .?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
490 views
Welcome To Ask or Share your Answers For Others

1 Answer

Automating an existing Visual Studio instance from an external tool to modify a loaded solution is a bad idea. If you use GetActiveObject(...) and there are two Visual Studio instances launched, how do you know that the correct instance is returned? And what if the user or Visual Studio is doing something with the solution when the user launches the external tool? There are two better approaches:

1) Use an external tool to automate a new Visual Studio instance, load the desired solution and modify it. This can be done even with the VS instance not visible. To create a new instance the proper code is:

System.Type type = Type.GetTypeFromProgID("VisualStudio.DTE.12.0");
EnvDTE.DTE dte = (EnvDTE.DTE) System.Activator.CreateInstance(type);
dte.MainWindow.Visible = true;
...

2) Use a Visual Studio extension, such as a macro (VS 2010 or lower), add-in (VS 2013 or lower) or package (any VS version) to provide a menu item or button toolbar that, when clicked, modifies the currently loaded solution. This prevent the "busy" scenario because if VS is busy the menu item or toolbar button can't be clicked (unless the "busy" operation is asynchronous).


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...