Add A Namespace Import Via Visual Studio Automation

Suppose you had a code document represented by a FileCodeModel object. And suppose you were modifying the containing DOM. Sometimes, you might need to add a namespace import to the document (i.e. “using …” in C# of “Import …” in VB). A namespace import is represented by the CodeImport interface. Reading out the namespace imports is easy:

var imports = fileCodeModel.CodeElements.OfType<CodeImport>();

But how do you add a new CodeImport element? Well, TIL that it’s worthwhile to look at all versions of an automation interface (e.g. FileCodeModel2 instead of just FileCodeModel). Sometimes, you might find just the method you were looking for 🙂 So the answer to the question in this case is:

var fileCodeModel = (FileCodeModel2)projectItem.FileCodeModel;
fileCodeModel.AddImport("My.New.Namespace");

Automatically Loading VSIX Packages

So you’re creating a VSIX package that does not have a menu items, tool windows or command? But still you want the package to get loaded (i.e. executed) by the IDE? What a crazy thing to wish for, one might think after spending hours searching the internet on how to do that. But don’t abandon hope, yet, since the answer is nigh.Read More »

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;

Write To Visual Studio’s Output Window

If you have developed a Visual Studio Extension, you might want to output messages to Visual Studio’s Output window. Here’s how to do it:

using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;

namespace MunirHusseini.Demos
{
    public class VsOutput
    {
        public static void Output(string msg)
        {
            // Get the output window
            var outputWindow = Package.GetGlobalService(typeof(SVsOutputWindow)) as IVsOutputWindow;

            // Ensure that the desired pane is visible
            var paneGuid = Microsoft.VisualStudio.VSConstants.OutputWindowPaneGuid.GeneralPane_guid;
            IVsOutputWindowPane pane;
            outputWindow.CreatePane(paneGuid, "General", 1, 0);
            outputWindow.GetPane(paneGuid, out pane);

            // Output the message
            pane.OutputString(msg);
        }
    }
}

Of course, you could output to other panels than just “General”. To do that, just change the value of the variable paneGuid. Possible values are:

BuildOutputPane_guid The build output pane inside the output window.
DebugPane_guid The debug pane inside the output window.
GeneralPane_guid The general output pane inside the output window.
SortedBuildOutputPane_guid The sorted build output pane inside the output window.
StoreValidationPane_guid The store validation pane inside the output window.

For a visual demonstration, please watch this video.