Category Archives: MZ-Tools Articles Series

MZ-Tools Articles Series: HOWTO: Create a command without user interface items from a Visual Studio package.

One of the most confusing things when starting with packages and you have a background of creating add-ins is how to create and name commands, which are not user interface items.

With add-ins, commands are created by code, and there are two separate steps: one to create the command (Commands2.AddNamedCommand2 method) and other step to create UI items (either temporary or permanent) such as menu items, toolbar buttons, etc. See:

HOWTO: Adding buttons, commandbars and toolbars to Visual Studio .NET from an add-in.

However, commands in packages are created by declarations in a .vsct file, and the separation between command and UI items is very blurry (and how to name a command is a subject for another post). For example, you have a <Commands> section, but commands are actually declared inside a <Buttons> section using <Button> elements. I can’t insist enough that in Visual Studio a command is not a button (or a menu item), and, in fact, sometimes your extension may want to provide a command without a user interface item. For example, if you want the command to be executed by default only with a keyboard shortcut. Or for some reason you need an “internal” command. My MZ-Tools add-in does this with at least one command.

So, I have written this article to show how you would create a command in a package without UI items:

HOWTO: Create a command without user interface items from a Visual Studio package

MZ-Tools Articles Series: HOWTO: Execute a command by Guid and Id from a Visual Studio package

There are a few articles / samples that I wrote in July but I forgot to blog about because I have been busy tuning this new web site and also I was a couple of weeks on vacation. This is the first of them.

Some years ago I wrote about executing a command by Guid and Id (rather than by name) from a VS add-in:

HOWTO: Execute a command by Guid and Id from a Visual Studio add-in
http://www.mztools.com/articles/2008/MZ2008013.aspx

As part of my strategy to moving from add-in to package for my MZ-Tools add-in, I want to get rid of EnvDTE as much as possible, so this is the equivalent using an automation-free approach to do the same:

HOWTO: Execute a command by Guid and Id from a Visual Studio package
http://www.mztools.com/articles/2014/MZ2014018.aspx

MZ-Tools Articles Series: HOWTO: Write to the output window panes from a Visual Studio package.

Today I am writing the equivalent of this article for add-ins that I wrote originally almost 6 years ago:

HOWTO: Get an OutputWindowPane to output some string from a Visual Studio add-in or macro
http://www.mztools.com/articles/2008/MZ2008023.aspx

but in this case natively (using services) for Visual Studio packages:

HOWTO: Write to the output window panes from a Visual Studio package.
http://www.mztools.com/articles/2014/MZ2014017.aspx

MZ-Tools Articles Series: HOWTO: Initialize the usercontrol of a toolwindow from a Visual Studio package.

Although creating a toolwindow and hosting a usercontrol in a Visual Studio package seems easy (thanks to the package wizard), initializing the usercontrol to receive an instance of your package (or the value of some property of your package) is somewhat tricky.

I have seen this question from time to time in the forums and until now my (wrong) answer was to use the ShowToolWindow event handler method of the package to get the instance of the usercontrol from the ToolWindowPane (using its Content property for WPF usercontrols and its Window property for Windows Forms usercontrols). Once you have the usercontrol instance, you can call a method of the usercontrol to pass it any piece of information that you want to initialize it. I won’t show the code because it is an incorrect approach due to this: when using a toolwindow in a package, if the last time that you closed Visual Studio the toolwindow was visible, the next time that you open Visual Studio the toolwindow will be shown automatically without the ShowToolWindow event handler method being called (so your usercontrol wouldn’t be initialized in that scenario).

This didn’t happen with add-ins (toolwindows were not open automatically in the next session if left open in the previous session). But with packages it happens, so the ShowToolWindow method of the package is not the proper place to initialize the usercontrol. Then, it must be done in the MyToolWindow class, which creates the usercontrol and it is always called, and fortunately it has a Package base property that you can use to get the instance of your package. Alas, that instance is null in the toolwindow constructor. My latest article shows a workaround:

HOWTO: Initialize the usercontrol of a toolwindow from a Visual Studio package
http://www.mztools.com/articles/2014/MZ2014016.aspx

MZ-Tools Articles Series: HOWTO: Host a Windows Forms usercontrol in a toolwindow from a Visual Studio package.

When you create a toolwindow with the Visual Studio package wizard, a Windows Presentation Foundation (WPF) usercontrol is used. If you are migrating an add-in to a package, chances are that your toolwindows use Windows Form usercontrols and you don’t want to change the forms technology (migrating the add-in to a package is enough work…). It happens that the way to host a usercontrol in a toolwindow is different for WPF and Windows Forms. In the former case you only have to assign the Content property to the instance of the usercontrol. If you do the same in the latter case, nothing happens (you don’t even get an exception). For Windows Forms usercontrols, you need to override the Window property to return the instance of the usercontrol.

My latest article explain it with sample code:

HOWTO: Host a Windows Forms usercontrol in a toolwindow from a Visual Studio package.
http://www.mztools.com/articles/2014/MZ2014015.aspx

MZ-Tools Articles Series: PRB: ‘Can not find the installation for VS SDK’ error using MSBuild of TFS to compile Visual Studio Package

I am using Visual Studio Online since a couple of months ago to great satisfaction adopting more and more of its features. One of them is continuous integration (CI) and gated check-ins. Yesterday I tried to check-in a modification of one of my add-ins converted to a Visual Studio package for the first time and the build failed with this error:

C:\Program Files
(x86)\MSBuild\Microsoft\VisualStudio\<version>\VSSDK\Microsoft.VsSDK.Common.targets
(line): Can not find the installation for VS SDK.

C:\Program Files
(x86)\MSBuild\Microsoft\VisualStudio\<version>\VSSDK\Microsoft.VsSDK.Common.targets
(line): The “FindVsSDKInstallation” task failed unexpectedly.
System.ArgumentNullException: Value cannot be null. Parameter name:
path1 at System.IO.Path.Combine(String path1, String path2)

C:\Program Files
(x86)\MSBuild\Microsoft\VisualStudio\<version>\VSSDK\Microsoft.VsSDK.Common.targets
(line): The “FindVsSDKInstallation” task’s outputs could not be
retrieved from the “IncludesPath” parameter. Value cannot be null.
Parameter name: path1

Searching the web I found several workarounds but some of them were too involved. I have documented the most easy ones to apply:

PRB: ‘Can not find the installation for VS SDK’ error using MSBuild of TFS to compile Visual Studio Package
http://www.mztools.com/articles/2014/MZ2014014.aspx

MZ-Tools Articles Series: HOWTO: Create a solution from a Visual Studio package.

During the last years I have written small, practical, articles with code samples about how to do things with Visual Studio add-ins like this:

HOWTO: Create a solution from a Visual Studio add-in
http://www.mztools.com/articles/2011/MZ2011001.aspx

And in the next years I hope to write lots of equivalent ones for Visual Studio packages, like this new one:

HOWTO: Create a solution from a Visual Studio package.
http://www.mztools.com/articles/2014/MZ2014013.aspx

MZ-Tools Articles Series: HOWTO: Get information about the loaded solution from a Visual Studio package.

Following with the second and third strategies migrating from Visual Studio add-ins to packages, after defining and implementing an IHost interface, likely you will continue with an ISolution interface with properties like:

public interface ISolution
{
   bool IsOpen { get;}
   string Name { get;}
   string FullFileName { get;}
   ...
}

Using the automation model (EnvDTE) you would use DTE.Solution to get the solution object and then the Solution.IsOpen, Solution.Name, Solution.FullName or Solution.Properties.Item(“Path”).Value properties and so on.

In this small article I explain how to use the IVsSolution interface of the SVsSolution service to avoid the use of EnvDTE.Solution to get some information about the loaded solution:

HOWTO: Get information about the loaded solution from a Visual Studio package.
http://www.mztools.com/articles/2014/MZ2014012.aspx

MZ-Tools Articles Series: HOWTO: Get information about the Visual Studio IDE from a Visual Studio package.

Two of the three strategies that I explained in my last post Strategies migrating from Visual Studio add-ins to packages involve to avoid the use of the automation model (EnvDTE). When you use an EnvDTE object, basically you do one of three things: to get/set properties, to invoke methods to perform actions and to get events. So, you need to learn how to do that with Visual Studio interfaces of services.

If you follow my third strategy, likely you will define an interface named IHost with some properties like this:

public interface IHost
{
   string RegistryRoot { get; }
   string InstallationFolder { get; }
   …
}

When implementing the RegistryRoot property of that interface using EnvDTE, you would use the DTE.RegistryRoot property. And to implement the InstallationFolder property, you would read the value “ProductDir” of the registry key HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\<version>\SetupVS.

When implementing those properties of the interface in your package, in this small article I explain how to use the IVsShell interface of the SVsShell service to avoid the use of EnvDTE.DTE to get some information about the Visual Studio IDE (the shell).

HOWTO: Get information about the Visual Studio IDE from a Visual Studio package.
http://www.mztools.com/articles/2014/MZ2014011.aspx