Category Archives: VS Packages

Resources to create high-DPI images with the new Visual Studio 2015 Image Service

In my post Visual Studio extensions and DPI-awareness I introduced the basics that you need to know to become DPI-aware. The final step once all the user interface of your extension handles high-DPI gracefully is to provide high-DPI images for the toolbars, as Visual Studio 2015 does since CTP 3. Apparently, support for high-DPI images through a new image service was in the Visual Studio 2015 RTM release, but it hasn’t been until a couple of days ago that Microsoft has published the MSDN documentation. Here you have the resources to learn and use it:

UPDATE (Jan 26, 2016): The Visual Studio Image Library, which contains .zip files with VS images, has been updated with VS 2015 images.

Announcing unified MZ-Tools 8.0 for Visual Studio, VBA (64-bit/32-bit), VB6 and VB5

It has been a long time since my last post here, and for a good reason. Since I released MZ-Tools 8.0 for Visual Studio 2015 last July 1 (converted from add-in to package), I have been very busy the last months to achieve a new huge milestone:

Announcing unified MZ-Tools 8.0 for Visual Studio, VBA (64-bit/32-bit), VB6 and VB5

From the extensibility point of view, MZ-Tools 8.0 is a unique piece in the world, AFAIK: it provides the same feature set for four different IDEs (Visual Studio, VBA editor, Visual Basic 6.0 and Visual Basic 5.0) with different extensibility APIs reusing the same code at binary level:

MZ-Tools 8.0 for Visual Studio (as package):
MZTools8VSPackage

MZ-Tools 8.0 for Visual Studio (as add-in):
MZTools8VSAddIn

MZ-Tools 8.0 for VBA:
MZTools8VBA

MZ-Tools 8.0 for VB6:
MZTools8VB6

MZ-Tools 8.0 for VB5:
MZTools8VB5

As you can see in the images, in all cases there is the same big MZTools8PlugIn.dll file, which contains the feature set, and smaller host adapter dlls that “plug” the features into the IDEs. If you are interested, I outlined the strategy to achieve this in this other post.

The strange case of CreatePkgDef failing because of strong name validation

After several days fixing bugs of my new MZ-Tools 8.0 version, today I have tried to run the build process that I have to generate the “Production” version and it has failed with this chain of errors:

Error 1 CreatePkgDef : error : ReflectionTypeLoadException: Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information. MZTools8VSPackage

Error 2 at System.Reflection.RuntimeModule.GetTypes(RuntimeModule module) MZTools8VSPackage

Error 3 at System.Reflection.RuntimeModule.GetTypes() MZTools8VSPackage

Error 4 at System.Reflection.Assembly.GetTypes() MZTools8VSPackage

Error 5 at Microsoft.VisualStudio.Tools.CreatePkgDef.ProcessAssembly(String fileName, Hive hive, PkgDefContext context, Boolean register, RegistrationMode mode) in f:\dd\VSSDK\VSIntegration\Tools\src\CreatePkgDef\CreatePkgDef.cs:line 260 MZTools8VSPackage

Error 6 at Microsoft.VisualStudio.Tools.CreatePkgDef.DoCreatePkgDef(InputArguments inputArguments) in f:\dd\VSSDK\VSIntegration\Tools\src\CreatePkgDef\CreatePkgDef.cs:line 164 MZTools8VSPackage

Error 7 at Microsoft.VisualStudio.Tools.CreatePkgDef.Main(String[] arguments) in f:\dd\VSSDK\VSIntegration\Tools\src\CreatePkgDef\CreatePkgDef.cs:line 85 MZTools8VSPackage

Error 8 Could not load file or assembly 'MZTools8PlugIn, Version=8.0.0.0, Culture=neutral, PublicKeyToken=a756ad4bac8a0579' or one of its dependencies. Strong name validation failed. (Exception from HRESULT: 0x8013141A) MZTools8VSPackage

The first thing I noticed is that the errors show a location “f:\dd\VSSDK\VSIntegration\Tools\src” that is not on my hard disk. This is because the VS SDK tools (at C:\Program Files (x86)\Microsoft Visual Studio 12.0\VSSDK\VisualStudioIntegration\Tools\Bin) are shipped with the .pdb files for debugging.

The second thing that I noticed is that the CreatePkgDef.exe utility was failing because of a strong name validation that happened in the System.Reflection.RuntimeModule.GetTypes(RuntimeModule module) method of the .NET Framework. However, this had been working until a few days ago. My MZ-Tools package (MZTools8VSPackage.dll) uses .NET Framework 4.5 and it is not obfuscated, but it uses a core MZTools8PlugIn.dll that uses .NET Framework 2.0 and it is obfuscated. So, the things are arranged as follows:

  • In “Debug” configuration, the MZTools8PlugIn.dll assembly is generated with a strong name because no obfuscation is performed.
  • In “Release” configuration, the MZTools8PlugIn.dll assembly is delay-signed, because it requires obfuscation, and you can’t alter an assembly signed with a strong name. So, obfuscation is done in a post-build step and then the obfuscated assembly is finally signed. The details are documented here.

So, in “Release” configuration, CreatePkgDef.exe is failing because the package assembly is loading a required assembly that doesn’t have a strong name yet (delay-sign). I was well aware that normally you need to instruct the .NET Framework to skip strong name validation using sn.exe -Vr (which for sn.exe 32-bit adds a special registry entry under HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\StrongName\Verification) but somehow the CreatePkgDef step of the package assembly compilation of my build process has been working for ages until a few days ago without that strong name validation skipping step.

What has changed in the last days? My only suspect was Visual Studio 2015 and .NET Framework 4.6, that I installed on my main dev machine once they got RTM status. Since .NET Framework 4.5, 4.5.1, 4.5.2 and 4.6 are “highly compatible” with .NET Framework 4.0, they are not installed “side by side” but “on top” of the previous version. But it could be that one version introduces a breaking change to existing apps. To verify this hypothesis, first on my main dev machine where the issue was happening I created a package with Visual Studio 2008 (which uses .NET Framework 3.5 and CLR 2.0) and it compiled even setting the following delay sign in the AssemblyInfo.cs file:

[assembly: AssemblyDelaySign(true)]

The same was not true if I used Visual Studio 2010 or higher (which use .NET Framework 4.0 / CLR 4.0 or higher), but it was true in the past. So the suspicion increases.

Then, I setup a new virtual machine with only Visual Studio 2013 (.NET Framework 4.5.2) and lo and behold, a package compiles even if you use delay sign:

VSPackageBuildWithNet45

As soon as I downloaded and installed  only .NET Framework 4.6 (no need to install Visual  Studio 2015), the same package compilation gets this error:

CreatePkgDef : error : FileLoadException: Could not load file or assembly 'VSPackage1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=69b8a83eb37e3459' or one of its dependencies. Strong name validation failed. (Exception from HRESULT: 0x8013141A)

VSPackageBuildWithNet46

So, .NET Framework 4.6 introduces a breaking change that I have not seen documented.

Now, there is at least a couple of solutions:

  • You can build the package assembly with a strong name even in “Release” configuration, so CreakePkgDef doesn’t fail, and remove the strong name before obfuscating. Since the sn.exe utility doesn’t allow to remove strong names, you must search some other utility on the web (they exist).
  • You can instruct the .NET Framework to skip strong name validation using sn.exe -Vr before the package assembly is built, not after the package is built and before the assembly is obfuscated. The utility sn.exe is so handy that it allows you to skip strong name validation for assemblies that don’t exist yet, specifying just the public key token that will be used to sign them:
sn.exe -Vr *,public_key_token

Visual Studio 2015 RTM just released

Finally Visual Studio 2015 RTM has been released today and I am installing now on my main dev machine, rather than on separate virtual machines as I have been doing until now. There is and there will be a lot of information about what’s new in this release, but as a developer of extensions for Visual Studio, this release introduces these changes that you must know:

  • Add-ins are gone and now packages are the primary way of extending Visual Studio for the typical need of creating some toolbar, menu, buttons, toolwindows, etc. or listening to events to do something. Migrating from an add-in to a package is not trivial due to the usage of services instead of the EnvDTE automation model (although you can still use the automation model) but also for the difficulties of the .vsct file. ElektroStudios StackOverflow user (and others): I do feel your pain. I will do my best to find time and provide decent tutorials and a GitHub sample about .vsct in the next couple of months.
  • The editions offering has been simplified a bit and now you have:
    • Community Edition, which supports extensibility and is free for some scenarios, at least “still free”, huh?
    • Professional Edition
    • Enterprise Edition
      All of them are already available. There is no Ultimate edition, but for some reason there are still Express editions for Windows Desktop, Web (both already available) and Windows 10 (coming soon).
  • The compilers for C# and VB.NET are now exposed to extensions through the .NET Compiler Platform (formerly “Roslyn”). This should replace the automation code models (EnvDTE.Project.CodeModel, EnvDTE.ProjectItem.FileCodeModel), although they can be still used and in fact their implementation has changed to use Roslyn under the hood, with quite a few bugs along the way that I have reported and most of them are fixed now.
  • There is new support for high resolution icons on buttons for high-dpi displays, although AFAIK it is not documented yet.
  • There is a new Common Project System (CPS) in the works.
  • The Visual Studio 2015 SDK is available as a separate download as until now, but it is also already included in the Visual Studio setup under the name Common Tools > Visual Studio Extensibility Tools:
    VS2015SDK
  • The way to create a package, to add commands and toolwindows has changed, as hinted in the setup:
    VS2015SDK_2
  • To create a package there is no longer a wizard as in Visual Studio 2013, but just a barebone VSIX project template, and later you add as many custom commands or custom toolwindows as you want using the Add > New Item dialog and selecting the corresponding item templates under the Extensibility node. This solves the old problem of how to add a second command or toolwindow to an existing package, at the cost of making it more difficult to know how to add the first ones.

I will elaborate on all these aspects in the next weeks (during my vacations, I’m afraid), and will provide new links on this site to VS 2015 specific stuff.

Did I mention that my extension MZ-Tools 8.0 is now a package for VS 2012, 2013 and 2015? It is also an add-in for VS 2005, 2008 and 2010, and they share 80% of code at binary level using the strategy of core plug-in +  host adapters that I outlined here. I have even released in the last weeks a restricted Beta 2 of MZ-Tools 8.0 for the VBA editor of Office and even for VB6 / VB5 sharing the same 80% of binary .NET code. This is an example of a complex add-in migrated to a package with a new good underlying architecture to accommodate not only future changes in the extensibility model of Visual Studio, but also to support other Microsoft IDEs.

MZ-Tools Articles Series: HOWTO: Guessing the IDE mode (design, debug or run-time) from a Visual Studio package

As I am moving from add-ins to packages, I always like to learn how to do things using native services of Visual Studio instead of using the automation model (EnvDTE). There is an area of Visual Studio extensibility, the debugger, that is very powerful but normally extensions don’t have to use, except maybe to know which mode (design-time, debug-time, run-time) the IDE is, and when the mode changes, because maybe some commands or features should be enabled/disabled based on the IDE mode.

Eight years ago I wrote how to do that using the automation model in this article:

HOWTO: Guessing the IDE mode (design, debug or run-time) from a Visual Studio add-in or macro

Today I have written a small equivalent article doing the same using the IVsDebugger native service:

HOWTO: Guessing the IDE mode (design, debug or run-time) from a Visual Studio package

The hidden and broken Generate Load Keys page (for VS 2005/2008 shell and packages)

I have found two questions in the last weeks about the somewhat hidden and broken web page to generate Package Load Keys (PLK) or Shell Load Keys (SLK). The first thing to know is that likely you don’t need them: for Visual Studio 2010 or higher, the load keys are not required. If you need them for Visual Studio 2005 / 2008, here are the things to know:

The public page is: https://msdn.microsoft.com/en-us/vstudio/cc655795.aspx

At the time of this writing , if you use Firefox you are missing the form to generate the keys, and you are missing even the warning that you are missing it:

GenerateLoadKeysFirefox

If you use Internet Explorer, you get the warning:

GenerateLoadKeysInternetExplorer

If in Internet Explorer you click the “Open this content in a new window” link, then you get finally the correct page (https://vsipprogram.com/External/key?iframe=true):

GenerateLoadKeys

There is other path to reach that page: you can become a Microsoft Visual Studio Industry Partner (VSIP) “Basic” level member (which is free) and:

  • At the bottom of the main page, click the “Support” link.
  • Click the “How do I get a PLK/SLK for Visual Studio?” FAQ entry link
  • You get a message:

“Since Visual Studio 2012 you no longer need a PLK or SLK to integrate with Visual Studio.

GenerateLoadKey

Bottom line: if you are creating VS 2005/2008 shell or packages, you can go directly to https://vsipprogram.com/External/key

MZ-Tools Articles Series: HOWTO: Get supported frameworks and profiles of a Visual Studio version from a package

Since Visual Studio 2008, a project can be built against different .NET Framework targets, versions and profiles. When you create a Visual Studio project, you get the first chance of selecting the target .NET Framework in the New Project dialog:

NewProject

If you change your mind later, you can go to the project properties dialog and change the target .NET Framework:

ProjectProperties

This capability is known as framework multi-targetting and in recent versions of Visual Studio has exploded to allow tons of different combinations of .NET Framework versions and profiles (.Net Framework, Silverlight, Windows Phone, XBox, .NET Microframework, .NET Portable, etc. You can read more in this post of MVP fellow Stephen Cleary: Framework Profiles in .NET.

Now, we will get to the code:

A combination of .NET Framework name, version and profile is known as .Net Framework “moniker”, and it has a display name (friendly name).

You can get the .Net Framework moniker that a project is targeting using automation (EnvDTE.Project.Properties.Item(“TargetFrameworkMoniker”).Value) or using the native services of Visual Studio (IVsHierarchy.GetProperty method with the __VSHPROPID4.VSHPROPID_TargetFrameworkMoniker property)

But more difficult is to know which are the available .NET Framework monikers, the display name of a moniker, the available assemblies for that moniker, etc. The interface to use is IVsFrameworkMultiTargeting and this new article of mine shows some sample code:

HOWTO: Get supported frameworks and profiles of a Visual Studio version from a package

The interface has more methods, so check the documentation.

BUG: Extension Manager of VS 2015 RC doesn’t show large image for installed extensions

While a couple of days ago I was testing the last .vsix installer of my MZ-Tools extension, now converted to a package, with Visual Studio 2015 Release Candidate, I discovered that its large image was not shown in the Extension Manager. At first I thought that it was my fault, because the VS SDK doesn’t warn you that a resource included in the extension.vsixmanifest (such as the license agreement) isn’t actually included in the package project. After fixing another bugs that were my fault, today I investigated this one, and it happens with all installed extensions, not only with mine. So, while browsing the Visual Studio Gallery (“Online” node of the tree), the large image is shown as expected. Here you have the Developer Assistant, for example:

VisualStudioGallery

But once you install it (“Installed” node of the tree), its large image is not shown, the ugly default one is used:

Installed

I have opened a bug on Microsoft Connect:

Extension Manager doesn’t show large image for installed extensions
https://connect.microsoft.com/VisualStudio/feedback/details/1391193/extension-manager-doesnt-show-large-image-for-installed-extensions

Hopefully it will be fixed for VS 2015 RTM. You can vote for it to make it so.

MZ-Tools Articles Series: HOWTO: Use the Browse for Folder dialog of Visual Studio from a package

Another question in the MSDN VSX Forum about the browser for folder dialog was intriguing enough for me to investigate. If you are using the .NET Framework since version 1.0 (like me), you may remember that that version didn’t provide a class, you had to use the native class of the Win32 API Shell, which was tricky. The FolderBrowserDialog was added in .NET Framework 1.1, and since then it has this appearance:

NetFolderBrowserDialog

Despite being in Spanish (the computer that I am using to write this post), you can guess that it provides a title, a description, a treeview and an optional button to allow the creation of a new folder without leaving the dialog.

However, Visual Studio uses this other dialog to select a folder in several places:

VisualStudioFolderBrowserDialog

Again, despite being in Spanish, you can guess that it provides a treeview to the left and a listview to the right, along with the button to create a new folder and, overall, somewhat better usability.

So, the question was how to leverage that Visual Studio dialog from a package. The answer lies in the IVsUIShell.GetDirectoryViaBrowseDlg method, and in this new article of mine you have a working example, because the API is awful, with arrays of structures, memory allocation, marshaling, etc:

HOWTO: Use the Browse for Folder dialog of Visual Studio from a package

MZ-Tools Articles Series: HOWTO Unload/Reload a project from a Visual Studio package

I have created two new articles/samples from a question that I addressed in the StackOverflow forum, about unloading / reloading a project programmatically. Using the automation model (EnvDTE) I knew the answers since many years ago:

DTE.ExecuteCommand(“Project.UnloadProject”)
DTE.ExecuteCommand(“Project.ReloadProject”)

However, that approach requires that the project is selected previously in the Solution Explorer. Furthermore, having migrated my MZ-Tools add-in to a Visual Studio package I am no longer happy when I have to use the old automation model and I am eager to investigate how to do things using native services. Alas, the investigation is never easy. In this case the IVsSolution interface provides the CloseSolutionElement method, which is not intuitive because it serves to unload many things, from the solution to a document, and certainly a project too. And it doesn’t seem to provide a method to reload a project. So, I opened the MSDN documentation for IVsSolution2, IVsSolution3, IVsSolution4, IVsSolution5 and IVsSolution6 interfaces and lo and behold, the IVsSolution4 interface has the answers in the UnloadProject / ReloadProject methods. If you remember, Visual Studio 2012 introduced asynchronous solution loading (something that seemed to start in Visual Studio 2010), so the new IVsSolution4 interface introduced quite a few methods that helps with that area. So, here are the samples:

HOWTO: Unload a project from a Visual Studio Package

HOWTO: Reload a project from a Visual Studio Package

Both methods require the project guid that identifies the project in the solution (not to confuse with the project type guid). You can get the project guid from a IVsHierarchy that represents a project calling the GetProperty method with the __VSHPROPID.VSHPROPID_ProjectIDGuid property. For VS 2010, alas, when the project is unloaded the “hierarchy stub” that represents the unloaded project in the solution doesn’t implement that property (it does in VS 2012 and higher). So, the second article applies to VS 2012 and higher (because it starts with an unloaded project as the initial condition), while the first could apply also to VS 2010.

Finally, for completeness sake, given a IVsHierarchy that represents an unloaded project you can get the unload reason calling the GetProperty method with the __VSHPROPID5.VSHPROPID_ProjectUnloadStatus property, which should return a value of the _VSProjectUnloadStatus enumeration.