Friday, July 11, 2008

Automate Visual Studio from external tools

While cleaning up a code monster, a colleague and I were looking for ways to dynamically rebuild all of our web-services as part of build script or utility as we have dozens of them and they change somewhat frequently.  In the end, we decided that we didn't necessarily need support for modifying them within the IDE and we could just generate them using the WSDL tool.

However, while I was researching the problem I stumbled upon an easy method to drive Visual Studio without having to write an addin or macro; useful for one-off utilities and hair-brain schemes.

Here's some ugly code, just to give you a sense for it.

You'll need references to:

  • EnvDTE - 8.0.0.0
  • VSLangProj - 7.0.3300.0
  • VSLangProj80 - 8.0.0.0
namespace AutomateVisualStudio
{
  using System;
  using EnvDTE;
  using VSLangProj80;

  public class Utility
  {
      public static void Main()
      {
          string projectPath = @"C:\Demo\Empty.csproj";
          Type type = Type.GetTypeFromProgID("VisualStudio.DTE.8.0");
          DTE dte = (DTE) Activator.CreateInstance(type);
          dte.MainWindow.Visible = false;

          dte.Solution.Create(@"C:\Temp\","tmp.sln");
          Project project = dte.Solution.AddFromFile(projectPath, true);

          VSProject2 projectV8 = (VSProject2) project.Object;
          if (projectV8.WebReferencesFolder == null)
          {
              projectV8.CreateWebReferencesFolder();
          }

          ProjectItem item = projectV8.AddWebReference("http://localhost/services/DemoWS?WSDL");
          item.Name = "DemoWS";
            
          project.Save(projectPath);
          dte.Quit();
      }
  }
}

Note that Visual Studio doesn't allow you to manipulate projects directly; you must load your project into a solution.  If you don't want to mess with your existing solution file, you can create a temporary solution and add your existing project to it.  And if you don't want to clutter up your disk with temporary solution files, just don't call the the Save method on the Solution object.

If you had to build a Visual Studio utility, what would you build?

submit to reddit

2 comments:

K.BhaskarReddy said...

hi please let me know how to add .cs files to the solution file

please provide the code

bryan said...

Solution files can't be compiled, so they support code files. All code elements must be added to a Project.

What you want to achieve is adding a ProjectItem to the ProjectItems collection on the Project.

project.ProjectItems.Add(...)

More info about the Visual Studio object model
can be found here.

Most code samples out there will refer to the context of building an Addin or Macro, which reside within Visual Studio. Those code samples can be ported to this scenario where the DTE object is the Visual Studio instance.