Logo
HOWTO: Create a project from a Visual Studio add-in inside a solution folder

Author: Carlos J. Quintero (Microsoft MVP) Applies to: Microsoft Visual Studio 2005
Date: July 2013   Microsoft Visual Studio 2008
Updated: February 2014   Microsoft Visual Studio 2010
      Microsoft Visual Studio 2012
      Microsoft Visual Studio 2013
Introduction

This article provides a sample to create a Visual Studio project from an add-in inside a solution folder, rather than belonging to the solution directly.

More Information

To add a first-level solution folder to a solution, you use the EnvDTE80.Solution2.AddSolutionFolder method. However, that method returns and EnvDTE.Project. You need to cast its Object property to EnvDTE80.SolutionFolder in other to use the EnvDTE80.SolutionFolder.AddFromTemplate method to add a projects.

Note: you can't add second-level solution folders using the automation model. See: PRB: NotImplementedException adding a solution folder to a solution folder in Visual Studio from a macro or add-in.

The following add-in, when loaded, creates a solution, a solution folder and a Windows Forms application project:

Language: C#   Copy Code Copy Code (IE only)
using System;
using Extensibility;
using EnvDTE;
using EnvDTE80;

namespace MyAddin1
{
   public class Connect : IDTExtensibility2
   {
      private DTE2 _applicationObject;
      private AddIn _addInInstance;

      public void OnConnection(object application, ext_ConnectMode connectMode, object addInInst, ref Array custom)
      {
         _applicationObject = (DTE2)application;
         _addInInstance = (AddIn)addInInst;

         switch (connectMode)
         {
            case ext_ConnectMode.ext_cm_AfterStartup:

               // The add-in has been loaded after Visual Studio was loaded. Since Visual Studio
               // is fully initialized, we can initialize the add-in
               InitializeAddIn();
               break;

            case ext_ConnectMode.ext_cm_Startup:

               // The add-in has been loaded with Visual Studio. Do nothing until Visual Studio 
               // is fully initialized (the OnStartupComplete method will be called)
               break;

            case ext_ConnectMode.ext_cm_UISetup:

               // Do nothing in this case
               break;
         }
      }

      public void OnStartupComplete(ref Array custom)
      {
         InitializeAddIn();
      }

      private void InitializeAddIn()
      {
         EnvDTE.Project solutionFolderProject;

         CreateSolution("MySolutionSubfolder", "MySolution");

         solutionFolderProject = CreateSolutionFolder("MySolutionFolder");

         CreateProject(solutionFolderProject, "MyProject", "WindowsApplication.zip", "CSharp");
      }

      private void CreateSolution(string solutionSubFolder, string solutionName)
      {
         string vsualStudioProjectsFolder;
         string solutionFullFolder;
         string solutionFullFileName;

         try
         {
            if (_applicationObject.Solution.IsOpen)
            {
               // Close the solution saving it
               _applicationObject.Solution.Close(true);
            }

            // Get the parent folder for Visual Studio projects
            vsualStudioProjectsFolder = GetVisualStudioProjectsFolder();

            // Get the folder where to save the solution
            solutionFullFolder = System.IO.Path.Combine(vsualStudioProjectsFolder, solutionSubFolder);

            // Important: if the folder doesn't exist, create it. Otherwise Visual Studio 
            // doesn't create it and a prompt is shown when the SaveAs method is called
            if (!System.IO.Directory.Exists(solutionFullFolder))
            {
               System.IO.Directory.CreateDirectory(solutionFullFolder);
            }

            // Compose the full name of the solution file
            solutionFullFileName = System.IO.Path.Combine(solutionFullFolder, solutionName + ".sln");

            // Create the solution
            _applicationObject.Solution.Create(solutionFullFolder, solutionName);

            // Save the solution
            _applicationObject.Solution.SaveAs(solutionFullFileName);

         }
         catch (Exception ex)
         {
            System.Windows.Forms.MessageBox.Show(ex.ToString());
         }

      }

      private EnvDTE.Project CreateSolutionFolder(string solutionFolderName)
      {
         EnvDTE80.Solution2 solution2;
         EnvDTE.Project solutionFolderProject;

         solution2 = (EnvDTE80.Solution2)_applicationObject.Solution;

         solutionFolderProject = solution2.AddSolutionFolder(solutionFolderName);

         return solutionFolderProject;
      }

      private void CreateProject(EnvDTE.Project solutionFolderProject, string projectName, string projectTemplateName, string language)
      {
         EnvDTE80.Solution2 solution2;
         EnvDTE80.SolutionFolder solutionFolder;
         string solutionFileFullName;
         string solutionFolderFullName;
         string projectTemplateFileFullName;
         string projectFolderFullName;

         try
         {
            solution2 = (EnvDTE80.Solution2)_applicationObject.Solution;

            // Get the full name of the solution file
            solutionFileFullName = solution2.FileName;

            // Get the full name of the solution folder
            solutionFolderFullName = System.IO.Path.GetDirectoryName(solutionFileFullName);

            // Compose the full name of the project folder
            projectFolderFullName = System.IO.Path.Combine(solutionFolderFullName, solutionFolderProject.Name);
            if (!(projectFolderFullName.EndsWith("\\")))
            {
               projectFolderFullName += "\\";
            }

            // Get the project template
            projectTemplateFileFullName = solution2.GetProjectTemplate(projectTemplateName, language);

            // Add the project to the solution folder
            solutionFolder = (EnvDTE80.SolutionFolder)solutionFolderProject.Object;
            solutionFolder.AddFromTemplate(projectTemplateFileFullName, projectFolderFullName, projectName);

         }
         catch (Exception ex)
         {
            System.Windows.Forms.MessageBox.Show(ex.ToString());
         }
      }

      private string GetVisualStudioProjectsFolder()
      {
         string version = "";
         string result;
         Microsoft.Win32.RegistryKey registryKey;

         switch (_applicationObject.Version)
         {
            case "8.0":
               version = "8.0";
               break;
            case "9.0":
               version = "9.0";
               break;
            case "10.0":
               version = "10.0";
               break;
            case "11.0":
               version = "11.0";
               break;
         }

         registryKey = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\VisualStudio\" + version);

         result = registryKey.GetValue("VisualStudioProjectsLocation").ToString();

         registryKey.Close();

         return result;
      }

      public void OnDisconnection(ext_DisconnectMode disconnectMode, ref Array custom)
      {
      }

      public void OnAddInsUpdate(ref Array custom)
      {
      }

      public void OnBeginShutdown(ref Array custom)
      {
      }
   }
}
Language: VB.NET   Copy Code Copy Code (IE only)
Imports System
Imports Extensibility
Imports EnvDTE
Imports EnvDTE80

Public Class Connect
   Implements IDTExtensibility2

   Private _applicationObject As DTE2
   Private _addInInstance As AddIn

   Public Sub OnConnection(ByVal application As Object, ByVal connectMode As ext_ConnectMode, _
        ByVal addInInst As Object, ByRef custom As Array) Implements IDTExtensibility2.OnConnection

      _applicationObject = CType(application, EnvDTE80.DTE2)
      _addInInstance = CType(addInInst, EnvDTE.AddIn)

      Select Case connectMode

         Case ext_ConnectMode.ext_cm_AfterStartup

            ' The add-in has been loaded after Visual Studio was loaded. Since Visual Studio
            ' is fully initialized, we can initialize the add-in
            InitializeAddIn()

         Case ext_ConnectMode.ext_cm_Startup

            ' The add-in has been loaded with Visual Studio. Do nothing until Visual Studio 
            ' is fully initialized (the OnStartupComplete method will be called)

         Case ext_ConnectMode.ext_cm_UISetup

            ' Do nothing in this case

      End Select

   End Sub

   Public Sub OnStartupComplete(ByRef custom As Array) Implements IDTExtensibility2.OnStartupComplete

      InitializeAddIn()

   End Sub

   Private Sub InitializeAddIn()

      Dim solutionFolderProject As EnvDTE.Project

      CreateSolution("MySolutionSubfolder", "MySolution")

      solutionFolderProject = CreateSolutionFolder("MySolutionFolder")

      CreateProject(solutionFolderProject, "MyProject", "WindowsApplication.zip", "VisualBasic")

   End Sub

   Private Sub CreateSolution(ByVal solutionSubFolder As String, ByVal solutionName As String)

      Dim vsualStudioProjectsFolder As String
      Dim solutionFullFolder As String
      Dim solutionFullFileName As String

      Try

         If _applicationObject.Solution.IsOpen Then

            ' Close the solution saving it
            _applicationObject.Solution.Close(True)

         End If

         ' Get the parent folder for Visual Studio projects
         vsualStudioProjectsFolder = GetVisualStudioProjectsFolder()

         ' Get the folder where to save the solution
         solutionFullFolder = System.IO.Path.Combine(vsualStudioProjectsFolder, solutionSubFolder)

         ' Important: if the folder doesn't exist, create it. Otherwise Visual Studio 
         ' doesn't create it and a prompt is shown when the SaveAs method is called
         If Not System.IO.Directory.Exists(solutionFullFolder) Then

            System.IO.Directory.CreateDirectory(solutionFullFolder)

         End If

         ' Compose the full name of the solution file
         solutionFullFileName = System.IO.Path.Combine(solutionFullFolder, solutionName & ".sln")

         ' Create the solution
         _applicationObject.Solution.Create(solutionFullFolder, solutionName)

         ' Save the solution
         _applicationObject.Solution.SaveAs(solutionFullFileName)

      Catch ex As Exception

         System.Windows.Forms.MessageBox.Show(ex.ToString())

      End Try

   End Sub

   Private Function CreateSolutionFolder(ByVal solutionFolderName As String) As EnvDTE.Project

      Dim solution2 As EnvDTE80.Solution2
      Dim solutionFolderProject As EnvDTE.Project

      solution2 = DirectCast(_applicationObject.Solution, EnvDTE80.Solution2)

      solutionFolderProject = solution2.AddSolutionFolder(solutionFolderName)

      Return solutionFolderProject

   End Function

   Private Sub CreateProject(ByVal solutionFolderProject As EnvDTE.Project, ByVal projectName As String, _
      ByVal projectTemplateName As String, ByVal language As String)

      Dim solution2 As EnvDTE80.Solution2
      Dim solutionFolder As EnvDTE80.SolutionFolder
      Dim solutionFileFullName As String
      Dim solutionFolderFullName As String
      Dim projectTemplateFileFullName As String
      Dim projectFolderFullName As String

      Try

         solution2 = CType(_applicationObject.Solution, EnvDTE80.Solution2)

         ' Get the full name of the solution file
         solutionFileFullName = solution2.FileName

         ' Get the full name of the solution folder
         solutionFolderFullName = System.IO.Path.GetDirectoryName(solutionFileFullName)

         ' Compose the full name of the project folder
         projectFolderFullName = System.IO.Path.Combine(solutionFolderFullName, solutionFolderProject.Name)
         If Not projectFolderFullName.EndsWith("\") Then
            projectFolderFullName &= "\"
         End If

         ' Get the project template
         projectTemplateFileFullName = solution2.GetProjectTemplate(projectTemplateName, language)

         ' Add the project to the solution folder
         solutionFolder = DirectCast(solutionFolderProject.Object, EnvDTE80.SolutionFolder)
         solutionFolder.AddFromTemplate(projectTemplateFileFullName, projectFolderFullName, projectName)

      Catch ex As Exception

         System.Windows.Forms.MessageBox.Show(ex.ToString())

      End Try

   End Sub

   Private Function GetVisualStudioProjectsFolder() As String

      Dim version As String = ""
      Dim result As String
      Dim registryKey As Microsoft.Win32.RegistryKey

      Select Case _applicationObject.Version

         Case "8.0"
            version = "8.0"

         Case "9.0"
            version = "9.0"

         Case "10.0"
            version = "10.0"

         Case "11.0"
            version = "11.0"

      End Select

      registryKey = Microsoft.Win32.Registry.CurrentUser.OpenSubKey("Software\Microsoft\VisualStudio\" & version)

      result = registryKey.GetValue("VisualStudioProjectsLocation").ToString()

      registryKey.Close()

      Return result

   End Function

   Public Sub OnDisconnection(ByVal disconnectMode As ext_DisconnectMode, ByRef custom As Array) _
      Implements IDTExtensibility2.OnDisconnection

   End Sub

   Public Sub OnAddInsUpdate(ByRef custom As Array) Implements IDTExtensibility2.OnAddInsUpdate
   End Sub

   Public Sub OnBeginShutdown(ByRef custom As Array) Implements IDTExtensibility2.OnBeginShutdown
   End Sub

End Class

Related articles



Go to the 'Visual Studio Extensibility (VSX)' web site for more articles like this (Articles section)


Top