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

Email this to someoneTweet about this on TwitterShare on LinkedInShare on FacebookShare on Google+

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

Email this to someoneTweet about this on TwitterShare on LinkedInShare on FacebookShare on Google+

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.

Email this to someoneTweet about this on TwitterShare on LinkedInShare on FacebookShare on Google+

MZ-Tools Articles Series: BUG: Visual Studio 2008 crashes if unloaded when an add-in executes DoEvents statement on startup

Although this article applies only to the old Visual Studio 2008, I am writing it for completeness of the body of knowledge that I have built over the years about add-ins. And if you are a VSX developer who cares about your users/customers, chances are that your extension still supports Visual Studio 2005 / 2008 (which are widely used yet at companies because for some reason developers don’t always migrate to the latest version. See How many old Visual Studio versions does my add-in/package have to support?). Recently I encountered an issue in one of my scripts that remove add-in commands, and it took me a while to find that the root cause was a bug in Visual Studio 2008:

BUG: Visual Studio 2008 crashes if unloaded when an add-in executes DoEvents statement on startup

If you were in the VSX world in the VS 2008 era of add-ins, you may remember that there was another bug that caused VS 2008 to crash on startup:

BUG: Add-in causes Visual Studio 2008 crash when loaded

Fortunately both bugs were fixed in next releases.

Email this to someoneTweet about this on TwitterShare on LinkedInShare on FacebookShare on Google+

New Project System Extensibility sections

One of the areas of Visual Studio Extensibility (VSX) that I am not very familiar with is project system extensibility, that is, creating new project types, extending project types with flavors (project subtypes) or creating custom tools (single file generators). I knew that that extensibility area was hard, though, as every piece of Visual Studio extensibility that was created around Visual Studio 2005 / 2008.

Yesterday, the time has come for a huge improvement in that area, when Microsoft made public a new Common Project System (CPS) Extensibility SDK in preview for Visual Studio 2015 that aims to simplify project type creation getting rid of MPFproj (“often containing well over 100K lines of code”).

I have noticed that this extensibility area was not well covered in this VSX site, that aims to provide pointers to every VSX bit of information out there, so I have created these new sections:

Email this to someoneTweet about this on TwitterShare on LinkedInShare on FacebookShare on Google+

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.

Email this to someoneTweet about this on TwitterShare on LinkedInShare on FacebookShare on Google+

Visual Studio 2015 RC quality good enough for extensions

I have been very stressed the last weeks in my spare time (nights and weekends) to ensure that the upcoming version 8.0 of my MZ-Tools extension works with Visual Studio 2015 CTPs and RC. This has been complicated because of these factors:

  • MZ-Tools 7.0 was an add-in, and MZ-Tools 8.0 will be a package.
  • MZ-Tools 8.0 for VS shares 80% of code with the also upcoming MZ-Tools 8.0 for VBA / VB, which is not yet finished.
  • VS 2015 belongs to my definition of “painful” category for extensions, because of the Roslyn-based implementation of the file code model.

Today, VS 2015 RC has passed for the first time the 3,300+ automated tests of MZ-Tools. And they are integration tests (not unit tests), each one testing a whole user-simulated scenario: clicking the options window of MZ-Tools, setting some options, clicking the button of a feature, capturing the result (either contents of an output toolwindow or generated code) and comparing with the expected result. They are able to detect subtle changes in the behavior of VS 2015 such as different automatic formatting, automatic removal of line continuation character “_” in VB.NET, automatic addition of parenthesis “()” to parameter-less VB.NET methods if the test omitted them, namespaces omitted from types in the Error List after a build, etc.  These are not really bugs but required to tweak the tests, in some cases maintaining backward compatibility with previous VS versions and in some cases detecting the VS version and using different code.

The tests also detected problems in the automation file code model (EnvDTE.ProjectItem.FileCodeModel), which I patiently isolated to root causes resulting in a total of 18 bugs that I have reported on GitHub, the last one, quite obscure, yesterday.  At the time of this writing, at least 15 are fixed (or will be fixed for VS 2015 RTM) and the remaining three ones have workarounds that I have coded to pass the tests.

So, at this point, VS 2015 RC is good enough from my point of view.

Email this to someoneTweet about this on TwitterShare on LinkedInShare on FacebookShare on Google+

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

Email this to someoneTweet about this on TwitterShare on LinkedInShare on FacebookShare on Google+

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.

Email this to someoneTweet about this on TwitterShare on LinkedInShare on FacebookShare on Google+

Microsoft fixing all bugs of FileCodeModel in VS 2015. And fast.

In this post I blogged about nine bugs introduced in the FileCodeModel of Visual Studio 2015 by the new Roslyn-based implementation. Those bugs were “critical” (that is, no easy workaround) and were fixed in the next days.

Then I reported two additional bugs that were less critical for me since I could implement workarounds:

EnvDTE.CodeElement GetStartPoint(EnvDTE.vsCMPart.vsCMPartBody).Line returns wrong result if declaration uses more than one line

EnvDTE80.CodeProperty2.ReadWrite returns always read-write value for VB.NET body-less properties

Those were fixed too. And two days ago I reported a couple of new critical bugs (no workaround) that I discovered:

EnvDTE.CodeFunction.FunctionKind causes COMException for Sub New() in VB.NET instead of returning vsCMFunction.vsCMFunctionConstructor

EnvDTE.CodeFunction.StartPoint, EndPoint, GetStartPoint, etc. cause exception for VB.NET “Declare Sub”/”Declare Function” methods

And those two have been already fixed on GitHub and will be in the some of the next Visual Studio 2015 CTPs.

It is also very incredible the level of transparency that Microsoft has now using open source for Roslyn on GitHub, where you can see the new code that fixes the bugs, the added unit tests, which MS developer is actually working on the fixes, who is reviewing them, etc.

So, thanks Microsoft for all!

Email this to someoneTweet about this on TwitterShare on LinkedInShare on FacebookShare on Google+

VS SDK, packages, add-ins, macros and more…