Logo
HOWTO: Create a project item from a Visual Studio add-in

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

This article provides a sample to create a Visual Studio project item (file) from an add-in.

More Information

The automation model (EnvDTE) allows you to add a project item (file) to the ProjectItems collection of a project (EnvDTE.Project.ProjectItems) or folder (EnvDTE.ProjectItem.ProjectItems) in three ways:

  • A new project item from a template.
  • An existing file from some location that is copied to the folder of the project.
  • An existing file from some location that is added from that location (linked).

The project templates that Visual Studio shows in the New Item dialog are stored in the folder C:\Program Files (x86)\Microsoft Visual Studio <version>\Common7\IDE\ItemTemplatesCache, where they are stored in folders that contain the programming language ("CSharp", "VisualBasic", etc.), technology ("Web", "Cloud", etc.) and locale ("1033", etc.).

The automation model (EnvDTE, EnvDTE80) provides the EnvDTE80.Solution2.GetProjectItemTemplate method to get a project item template file name given the project item template name (such as "Class") and the programming language (such as "CSharp" or "VisualBasic").

Once you have the template file name, you can add a project item to a ProjectItems collection using the AddFromTemplate method. Note: this method returns null (Nothing) rather than the EnvDTE.ProjectItem created, so you may need to locate the created project item in the ProjectItems collection. See PRB: Solution.AddXXX and ProjectItems.AddXXX methods return Nothing (null).

If you want to add an existing file, you can use the ProjectItems.AddFromFileCopy or ProjectItems.AddFromFile methods.

The following add-in, when loaded, adds the following to the first project of the solution:

  • A new class file under the project.
  • A new class file under a new folder of the project.
  • An existing file copied.
  • An existing file linked.
Language: C#   Copy Code Copy Code (IE only)
using System;
using Extensibility;
using EnvDTE;
using EnvDTE80;

namespace MyAddIn
{
    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;
            }
        }

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

        private void InitializeAddIn()
        {
            EnvDTE80.Solution2 solution2;
            EnvDTE.Project project;
            EnvDTE.ProjectItem folderProjectItem;
            string projectItemTemplate;
            string language = null;
            string extension = null;
            string folderFullName;
            string existingProjectItem1FullName;
            string existingProjectItem2FullName;

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

                if (_applicationObject.Solution.Projects.Count > 0)
                {
                    project = _applicationObject.Solution.Projects.Item(1);

                    switch (project.CodeModel.Language)
                    {
                        case EnvDTE.CodeModelLanguageConstants.vsCMLanguageCSharp:
                   
                            language = "CSharp";
                            extension = ".cs";
                            break;

                        case EnvDTE.CodeModelLanguageConstants.vsCMLanguageVB:
                           
                            language = "VisualBasic";
                            extension = ".vb";
                            break;
                    }

                    if (!String.IsNullOrEmpty(language))
                    {
                        // Get the template for "class" files for the given language
                        projectItemTemplate = solution2.GetProjectItemTemplate("Class", language);

                        // Add a new file from the template under the project
                        project.ProjectItems.AddFromTemplate(projectItemTemplate, "NewClassInProject" + extension);

                        // Create a new folder under the project
                        folderProjectItem = project.ProjectItems.AddFolder("My folder");

                        // Add a new file from the template under the folder
                        folderProjectItem.ProjectItems.AddFromTemplate(projectItemTemplate, "NewClassInFolder" + extension);

                        // Create existing files in the "My Documents" folder
                       
                        folderFullName = System.Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
                       
                        existingProjectItem1FullName = System.IO.Path.Combine(folderFullName, "ExistingClass1" + extension);
                        System.IO.File.WriteAllText(existingProjectItem1FullName, "");
                       
                        existingProjectItem2FullName = System.IO.Path.Combine(folderFullName, "ExistingClass2" + extension);
                        System.IO.File.WriteAllText(existingProjectItem2FullName, "");

                        // Add an existing file to the project creating a copy under the project
                        project.ProjectItems.AddFromFileCopy(existingProjectItem1FullName);

                        // Add another existing file to the project from its original location (link)
                        project.ProjectItems.AddFromFile(existingProjectItem2FullName);
                    }
                }
            }
            catch (Exception ex)
            {
                System.Windows.Forms.MessageBox.Show(ex.ToString());
            }
        }

        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 Microsoft.VisualStudio.CommandBars
Imports Extensibility
Imports EnvDTE
Imports EnvDTE80

Public Class Connect
    Implements Extensibility.IDTExtensibility2

    Private _applicationObject As EnvDTE.DTE
    Private _addInInstance As EnvDTE.AddIn

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

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

        Select Case connectMode

            Case ext_ConnectMode.ext_cm_AfterStartup
                InitializeAddIn()

            Case ext_ConnectMode.ext_cm_Startup
                ' OnStartupComplete will be called

        End Select

    End Sub

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

        InitializeAddIn()

    End Sub

    Private Sub InitializeAddIn()

        Dim solution2 As EnvDTE80.Solution2
        Dim project As EnvDTE.Project
        Dim folderProjectItem As EnvDTE.ProjectItem
        Dim projectItemTemplate As String
        Dim language As String = Nothing
        Dim extension As String = Nothing
        Dim folderFullName As String
        Dim existingProjectItem1FullName As String
        Dim existingProjectItem2FullName As String

        Try

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

            If (_applicationObject.Solution.Projects.Count > 0) Then

                project = _applicationObject.Solution.Projects.Item(1)

                Select project.CodeModel.Language

                    Case EnvDTE.CodeModelLanguageConstants.vsCMLanguageCSharp

                        language = "CSharp"
                        extension = ".cs"

                    Case EnvDTE.CodeModelLanguageConstants.vsCMLanguageVB

                        language = "VisualBasic"
                        extension = ".vb"

                End Select

                If Not String.IsNullOrEmpty(language) Then

                    ' Get the template for "class" files for the given language
                    projectItemTemplate = solution2.GetProjectItemTemplate("Class", language)

                    ' Add a new file from the template under the project
                    project.ProjectItems.AddFromTemplate(projectItemTemplate, "NewClassInProject" + extension)

                    ' Create a new folder under the project
                    folderProjectItem = project.ProjectItems.AddFolder("My folder")

                    ' Add a new file from the template under the folder
                    folderProjectItem.ProjectItems.AddFromTemplate(projectItemTemplate, "NewClassInFolder" + extension)

                    ' Create existing files in the "My Documents" folder

                    folderFullName = System.Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)

                    existingProjectItem1FullName = System.IO.Path.Combine(folderFullName, "ExistingClass1" + extension)
                    System.IO.File.WriteAllText(existingProjectItem1FullName, "")

                    existingProjectItem2FullName = System.IO.Path.Combine(folderFullName, "ExistingClass2" + extension)
                    System.IO.File.WriteAllText(existingProjectItem2FullName, "")

                    ' Add an existing file to the project creating a copy under the project
                    project.ProjectItems.AddFromFileCopy(existingProjectItem1FullName)

                    ' Add another existing file to the project from its original location (link)
                    project.ProjectItems.AddFromFile(existingProjectItem2FullName)

                End If

            End If

        Catch ex As Exception

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

        End Try

    End Sub

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

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

    Public Sub OnDisconnection(ByVal RemoveMode As Extensibility.ext_DisconnectMode, ByRef custom As System.Array) _
       Implements Extensibility.IDTExtensibility2.OnDisconnection
    End Sub

End Class

Related articles


Go back to the 'Resources for Visual Studio .NET extensibility' section for more articles like this


Top