MZ-Tools Articles Series: HOWTO: Create a command with a custom picture using an ImageList for a XML-based Visual Studio add-in.

This one that I mentioned in my last post that I would investigate has been extremely easy:

HOWTO: Create a command with a custom picture using an ImageList for a XML-based Visual Studio add-in.
http://www.mztools.com/articles/2012/MZ2012005.aspx

And Microsoft updated correctly the documentation for Visual Studio 2010 regarding the new possibilities of the Bitmap parameter of the EnvDTE80.Commands2.AddNamedCommand2 method:

EnvDTE80.Commands2.AddNamedCommand2
http://msdn.microsoft.com/en-us/library/envdte80.commands2.addnamedcommand2(VS.100).aspx

MZ-Tools Articles Series: HOWTO: Create a command with a custom picture without using a managed satellite DLL for a XML-based Visual Studio add-in.

I should have written the following article near two years ago, but also Microsoft should have provided this way of creating commands with custom pictures without the need for satellite dlls 10 years ago, since the very beginning of VS.NET 2002:

HOWTO: Create a command with a custom picture without using a managed satellite DLL for a XML-based Visual Studio add-in.
http://www.mztools.com/articles/2012/MZ2012004.aspx

The history has been quite compolicated:

  • Visual Studio .NET 2002 and 2003 only supported COM-based add-ins that required native Visual C++ Win32 satellite dlls to provide custom pictures.
  • Visual Studio 2005 introduced XML-based add-ins (using an .AddIn file to register the add-in within Visual Studio) and managed (VB.NET/C#) satellite dlls.
  • As documented in the Microsoft Connect Bug Report 336868, I requested to Microsoft during the VS 2010 beta to following: “Satellite DLLs (managed or native) should not be required. They may be OK for string localizations, but please don’t force us to create satellite DLLs for pictures that could be in the own assembly add-in.”
  • In the same bug report, Suzanne Hansen (the Program Manager of Visual Studio Platform Shell Team at that time) answered that (in VS 2010) “There will be support for loading a command’s bitmap from the add-in module if there is no satellite DLL or if the satellite DLL doesn’t contain the image.”
  • And that was my knowledge of the matter until two days ago, when while writing the add-ins for the article I discovered that Visual Studio 2008 already supported providing custom pictures in a resource file of the add-in dll rather than through a satellite dll. Alas, the same doesn’t apply to Visual Studio 2005, which insists on finding a “.resources.dll” satellite assembly, which is a pity, because if your add-in targets VS 2005, 2008 and 2010 with the same .NET Framework 2.0 dll, you need to provide the satellite dll.
  • And there is more! As I posted back in 2009, the EnvDTE80.Commands2.AddNamedCommand2 was changed internally in VS 2010 to accept a managed (.NET) System.Drawing.Bitmap or System.Drawing.Icon. I will try it and this will be the subject of another article if I am successful.

VS11 Beta bug: it does not raise AppDomain.AssemblyResolve to receive the satellite dll in add-ins in localized versions

The approach that I described in the following article to use a single satellite Dll with the “en-US” culture using the AppDomain.AssemblyResolve event doesn’t work in VS 11 Beta:

HOWTO: Create a command with a custom picture using a managed satellite DLL for a XML-based Visual Studio add-in.
http://www.mztools.com/articles/2012/MZ2012002.aspx

I have just opened a bug report at Microsoft Connect:

VS11 Beta does not raise AppDomain.AssemblyResolve to receive the satellite dll in add-ins in localized versions
https://connect.microsoft.com/VisualStudio/feedback/details/731914/vs11-beta-does-not-raise-appdomain-assemblyresolve-to-receive-the-satellite-dll-in-add-ins-in-localized-versions#details

BTW, some other bugs that I have been reporting will be fixed in next builds of VS 11, according to the Microsoft answers. Hopefully this is fixed too.

MZ-Tools Articles Series: HOWTO: Set the default style a CommandBarButton on a toolbar from a Visual Studio add-in.

When a CommandBarButton is created from a Command on a Visual Studio menu, it has an icon and a text. However, when it is created on a toolbar, it can have only an icon, or an icon and a text. Typically buttons on a toolbar have only an icon (without a text). There are two ways to set that style (only the icon) to a CommandBarButton on a toolbar:

  • Setting the CommandBarButton.Style = MsoButtonStyle.msoButtonIcon. This approach has the drawback that Visual Studio first creates the button with icon and text, and then it changes it to icon only.
  • Setting the default style of a command to EnvDTE80.vsCommandStyle.vsCommandStylePict, so that CommandBarButtons created on toolbars have only the icon, while those created on menus have icon with text (the only possible style for them).

My latest article shows a sample of the second approach:

HOWTO: Set the default style a CommandBarButton on a toolbar from a Visual Studio add-in.
http://www.mztools.com/articles/2012/MZ2012003.aspx

MZ-Tools Articles Series: HOWTO: Create a command with a custom picture using a managed satellite DLL for a XML-based Visual Studio add-in.

I have created a new article that shows a whole example of an add-in creating a command and a button with a custom picture using a satellite managed (.NET) dll:

HOWTO: Create a command with a custom picture using a managed satellite DLL for a XML-based Visual Studio add-in.
http://www.mztools.com/articles/2012/MZ2012002.aspx

While I had the article HOWTO: Creating custom pictures for Visual Studio .NET add-ins commands, buttons and toolwindows, it was not supplying a whole example of a working add-in. The next version of my MZ-Tools add-in will switch from being a COM-based add-in with a native satellite dll to a XML-based add-in with a managed (.NET) satellite dll, and I have found quite a few issues until it worked fine. One of them was that I wanted a single satellite dll, not one dll for each culture (“en-US”, “es-ES”, etc.) and finally I found a nice trick to accomplish that, using the AppDomain.AssemblyResolve event.

If you have followed my blog last years, you know how much I hate satellite dlls so after 4 years I finally got Microsoft to get rid of them in Visual Studio 2010 (bad luck if you want to support Visual Studio 2005 and 2008. Update: it happens that the approach also works in VS 2008). My next article will show a whole example.

VS 11 Beta issue for add-ins and extensions: asynchronous solution loading

In the Visual Studio blog it has been published the expected Visual Studio 11 Beta Performance Part #2 about changes in the solution loading experience that can explain the issues that I posted some days ago:

VS 11 Beta issue: EnvDTE.Project.CodeModel returns null for a project just loaded without open documents
https://www.visualstudioextensibility.com/2012/03/09/vs-11-beta-issue-envdte-project-codemodel-returns-null-for-a-project-just-loaded-without-open-documents

VS 11 Beta issue: EnvDTE.SolutionEvents.Opened event not fired for a solution just loaded without open documents
https://www.visualstudioextensibility.com/2012/03/09/vs-11-beta-issue-envdte-solutionevents-opened-event-not-fired-for-a-solution-just-loaded-without-open-documents

As the article explains, solution loading is now done in two phases, one “modal loading” in the main UI thread, and other “background loading”, which has important effects on extensions (add-ins, packages, etc.). Specifically the article explains why the previous issues only happen when there are no files open from the last session:

During the Modal Loading phase, we load projects most likely to be needed by the user and block the UI thread to ensure this task has the highest priority. Specifically, we create only the projects that had files left open in the last VS session or projects. We rely on the new Preview Tab feature (discussed here) to help ensure that only projects that you were actively working with in your last session are loaded in this phase of solution load. (…) Finally, we notify components and extensions that the Modal Load phase of solution loading is about to complete, so they can initialize their data models.

and:

In the Background Loading phase, we unblock the UI thread and start processing the background load tasks one at a time. Each time a project is loaded in the background, we notify components and extensions that the project has loaded.  If the user requests information about a project that has not finished loading, we immediately load that project and its dependencies (on the UI thread for maximum performance). We made this operation cancellable if you don’t want to wait. Once all project loading tasks have been processed we notify all components and extensions that the Background Loading phase of solution load has completed.

So, it seems that VS 11 notifies extensions when each project has finished loading, when the Modal Loading phase is about to complete and when the Background Loading phase has completed. The question is how add-in extensions are notified since the EnvDTE.SolutionEvents only has a Opened event and there are no events for projects, I guess that for packages new services are introduced in the SDK and Microsoft is working with “popular extensions” to address the changes and issues, but for add-ins I am not sure if new events will be introduced in the EnvDTE automation model. Maybe we will have more information when Microsoft answers the two Microsoft Connect issues that I opened.

VS 11 Beta: language packs

One new “feature” of Visual Studio 11 is that it will support language packs to provide multiple languages for the user interface (UI). You can download them for VS 11 Beta here:

Microsoft Visual Studio 11 Beta Language Pack
http://www.microsoft.com/en-us/download/details.aspx?id=30681

This is something I wanted to have since long time ago (I wish Visual Studio had Multilingual User Interface (MUI) implemented as on Windows Vista). And finally Microsoft has provided this. While multiple languages for the UI is not important for most developers (they will use only one), it is a very important feature for developers of add-ins and other extensions. Why? Because chances are that you will develop your extension in Visual Studio in English and it will fail when some user uses Visual Studio in Spanish, German, French, etc. In the following post I explained things to be aware of:

MZ-Tools Articles Series: HOWTO: Testing add-ins in localized versions of Visual Studio
https://www.visualstudioextensibility.com/2010/04/01/mz-tools-articles-series-howto-testing-add-ins-in-localized-versions-of-visual-studio

(In a next post I will talk about another area to take into account: the language of the satellite dlls used by add-ins to provide custom pictures for commands and buttons, which depend on the language of Visual Studio, but I found a workaround to use only one satellite dll.)

Until now, you had to install the full Visual Studio in some language on top of the Visual Studio in some other language (and the service packs) to get the two languages in the “Tools”, “Options” window, “Environment”, “International Settings” section. Now, you can just install a language pack on top of the Visual Studio in some language, which supposedly will take less time.

But Visual Studio is half of the environment. The other half is the Windows operating system, which also varies from one language to another, and some folders are localized (for example, “Application Data” in Windows XP), which can cause bugs if you are not careful as the bug of Visual Studio described in the post mentioned above. To catch these problems since I have two computers in one of them I have Windows and Visual Studio in Spanish (my native language) and in other in English. Of course you can use virtual machines for foreign languages if English is your native language.

VS 11 Beta issue: EnvDTE.SolutionEvents.Opened event not fired for a solution just loaded without open documents

Another issue related to my last post  VS 11 Beta issue: EnvDTE.Project.CodeModel returns null for a project just loaded without open documents is the following: the SolutionEvents.Opened event is not fired when you open a solution that was closed previously with all documents closed. Furthermore, the event is not firing when you open some document!.

The bug report is the following:

EnvDTE.SolutionEvents.Opened event not fired for a solution just loaded without open documents
https://connect.microsoft.com/VisualStudio/feedback/details/730000/envdte-solutionevents-opened-event-not-fired-for-a-solution-just-loaded-without-open-documents#details

VS 11 Beta issue: EnvDTE.Project.CodeModel returns null for a project just loaded without open documents

Two of the unit tests of my MZ-Tools add-in failed due to a change in VS 11 Beta that took me a couple of hours to isolate: if your add-in opens a solution and no document is open (for example, because the solution was closed previously with all documents closed), the EnvDTE.Project.CodeModel property returns null. In previous Visual Studio version you could get the code model of a project even if none of its files was opened. It happens that my add-in needs to know the language of the projects of the solution, using the Project.CodeModel.Language property.

At the time of this writing I am waiting for the Visual Studio 11 Beta Performance Part #2 post on the Visual Studio blog that according to Part #1 will explain the changes loading solutions in VS 11 to perform better, which I suspect are related to this issue.

Meantime, here it is the Microsoft Connect bug report that I have opened:

EnvDTE.Project.CodeModel returns null for a project just loaded without open documents
https://connect.microsoft.com/VisualStudio/feedback/details/729987/envdte-project-codemodel-returns-null-for-a-project-just-loaded-without-open-documents#details

VS 11: Target framework combobox now in “Application” section of VB.NET Project Properties

Since Visual Studio 2008 introduced multi-targeting .NET Framework, one weird thing of VB.NET projects was that to change the .NET Framework of a VB.NET application you had to go to the project properties window, “Compile” section (whose settings depend on the Configuration and Platform!), click the “Advanced Compiled Options…” and then you had a “Target framework (all configurations)” combobox. Meantime C# projects used the natural location for that combobox: the “Application” section, whose settings don’t depend on the Configuration and Platform.

VS 11 Beta finally fixes this issue for VB.NET projects and the “Target framework” combobox now belongs to the “Application” section, its natural place and much more visible.

The automation model (EnvDTE) for add-in and macros was right and the “TargetFramework” property belongs to the application (EnvDTE.Project.Properties), as shown in my article:

HOWTO: Get the target .NET Framework of a Visual Studio 2008 project from a Visual Studio add-in or macro
http://www.mztools.com/articles/2008/MZ2008015.aspx