Adding Solution Folders Via Visual Studio Automation

In the Visual Studio Solution Explorer, you can add solution folders to group projects or project items. These solution folders do not represent folders in the file system but are merely virtual. Adding these folders in the Solution Explorer is a trivial task, but how do you do that in code via EnvDTE? Continue reading

Get The ProjectItem of a T4 Template From Inside the T4 Template

So you got a T4 template and need access to the ProjectItem of that T4 template or to the parent Project of the T4 template? Here’s how:

1) Set the template’s hostspecific attribute to true and reference the Visual Studio Automation assemblies.

<#@ template debug="false" hostspecific="true" language="C#" #>
<#@ assembly name="envdte" #>
<#@ assembly name="envdte80" #>
<#@ import namespace="EnvDTE" #>

2) Get the Project or ProjectItem using Visual Studio Automation.

// By setting the template's 'hostspecific' property to true, 
// we get access to the text templating engine host 
// which implements IServiceProvider.
var serviceProvider = (IServiceProvider)this.Host;

// Get the automation root object
var dte = (EnvDTE.DTE)serviceProvider.GetService(typeof(EnvDTE.DTE));

// Get the project item
var projectItem = dte.Solution.FindProjectItem(this.Host.TemplateFile);

// Get the project
var project = projectItem.ContainingProject;

Tell if an EnvDTE.Project is a Web Application

A Visual Studio Extension or Add-In might need to know whether or not a project is a web application (in my case, I needed to know whether I’ll expect app.congig or web.config). Due to a bug in Visual Studio, that is not so straight-forward. But thanks to Carlos J. Quintero, I got some code together.

If you need it, suit yourselves.

using System.Linq;
using EnvDTE;

namespace MuniHusseini.Demos
{
        public static bool IsWebProject(this Project project)
        {
            return project.Object is VsWebSite.VSWebSite || project.ProjectHasExtender("WebApplication");
        }

        public static bool ProjectHasExtender(this Project proj, string extenderName)
        {
            // See http://www.mztools.com/articles/2007/mz2007014.aspx for more information.

            try
            {
                // We could use proj.Extender(extenderName) but it causes an exception if not present and 
                // therefore it can cause performance problems if called multiple times. We use instead:

                var extenderNames = (object[])proj.ExtenderNames;

                return extenderNames.Length > 0 && extenderNames.Any(extenderNameObject => extenderNameObject.ToString() == extenderName);
            }
            catch
            {
                // Ignore
            }

            return false;
        }
    }
}

Convert IVsHierarchy to ProjectItem or Project

The title says it all… here you go:

Microsoft.VisualStudio.Shell.Interop.IVsHierarchy hierarchy = // ... get it.

// VSITEMID_ROOT gets the current project. 
// Alternativly, you might have another item id.
var itemid = VSConstants.VSITEMID_ROOT; 

object objProj;
hierarchy.GetProperty(itemid, (int)__VSHPROPID.VSHPROPID_ExtObject, out objProj);

var projectItem = objProj as EnvDTE.ProjectItem;
// ... or ...
var project = objProj as EnvDTE.Project;

Thanks to Ed Dore in the Visual Studio forums.