“Creative” solutions from developers to avoid the satellite dll in Visual Studio add-ins

It always fascinates me how “creative” we the developers can be solving problems that shouldn’t exist in the first place. For example, Microsoft has been too much creative in the last decade providing multiple tricky ways to solve the lack of transparency support in the original bitmap format. And now I am seeing in several places an approach that developers of add-ins are using to avoid the satellite DLLs to provide custom pictures. The first place where I saw it was in the very MSDN documentation about displaying a custom icon on the add-in button, in the Community Content section by Miguel Ferreira.

The basic idea is to give up the picture of the command, and to modify the picture of the CommandBarButton created from the command through its Picture and Mask properties. The implementation gets more complicated because those properties have the COM IPictureDisp type and therefore conversions from managed System.Drawing.Bitmap are required, and another creative technique is used to get the mask from a picture pixel by pixel rather than providing it directly (which would force to create two bitmaps per button).

I flagged that community content as “bug” because it doesn’t solve the fundamental problem, that is, providing a picture for the command, not just for its buttons. The picture of a command is something totally visible to the user when she clicks the “Tools”, “Customize” menu, “Commands” tab, “Add-Ins” section. While it may seem not very important a lacking command picture there, it happens that with that window open VS enters in a special mode that allows the user to drag the command on a toolbar to create a button, and the button would get the picture of the command.

I saw this approach too yesterday in this post of Roy Osherove.

Fortunately these hacks won’t be necessary in VS 2010, which will get rid of satellite DLLs for add-ins “officially”.

Issues with the grayscale image generated by Visual Studio for disabled commandbar buttons

I am now investigating why the grayscale image that Visual Studio 2005 / 2008 generates for a disabled button is so horrible/blurry for pictures of add-in commands and so crisp and precise for pictures of VS commands. VS 2005 introduced True Color bitmaps (VS.NET 2003 used 16-color bitmaps) so it should be able to generate good-looking grayscale images as it does with its own pictures (if I am correct that the disabled image is autogenerated and not provided separately through some way not available to add-ins). There are two scenarios where disabled buttons look bad:

  • CommandBarButtons created from a command (via Command.AddControl). In this case the image of the button is actually the image of the command which in turn is supplied in a satellite dll in True Color (24 bit) bitmap format, so there is no much room to play…
  • CommandBarButtons created on a CommandBar created by the add-in to be used as context menu somewhere, for example in the context menu of a list (New, Remove, etc.). The add-in creates a VS commandbar rather than a .NET context menu to provide the same look and feel. In this scenario, there is no command, the CommandBarButton is created via CommandBar.Controls.Add. When you cast the returned CommandBarControl to CommandBarButton you can use the Picture and Mask properties (COM IPictureDisp type) to set the image and the transparency mask, so there is much more room to play with the bitmap format, the color depth (32-bit, 24-bit, 8-bit), and how you get a COM IPictureDisp from a managed System.Drawing.Bitmap.

So far I have been unable to solve this, I will post again if I find a resolution for this issue. If someone know the solution, let me know.

Button custom picture transparency issues in Office extensibility too

I have found today three links on the web about issues with transparency in custom pictures of buttons that Office add-ins have suffered too:

Alpha channels, masks, color keys, oh my! (By Eric Faller about the Office Ribbon)
http://blogs.msdn.com/jensenh/archive/2006/11/27/ribbonx-image-faq.aspx

How To Create a Transparent Picture For Office CommandBar Buttons (MSDN KB Article)
http://support.microsoft.com/kb/288771

How To Set the Mask and Picture Properties for Office XP CommandBars (MSDN KB Article)
http://support.microsoft.com/kb/286460

Given that Visual Studio borrowed its commandbars from Office, it’s no wonder it has suffered the same problems.

More on devenv.exe /resetaddin not removing permanent commandbars

I think I forgot to blog about the resolution of this bug:

devenv.exe /resetaddin doesn’t fully reset the add-in
https://www.visualstudioextensibility.com/2009/06/23/devenv-exe-resetaddin-doesn-t-fully-reset-the-add-in

whose Microsoft Connect bug report is:

https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=469322

The problem is, you see, that devenv.exe /resetaddin doesn’t remove permanent commandbars, only commands and buttons on commandbars. That means that if you are using permanent commandbars and not temporary ones, at the very least your uninstaller needs to take care of removing permanent commandbars explicitly because devenv.exe /resetaddin won’t do it. This can be done creating an instance of EnvDTE.DTE, locating the commandbar and calling EnvDTE.DTE.Commands.RemoveCommandBar (see HOWTO: Removing commands and UI elements during Visual Studio .NET add-in uninstallation). And not only the uninstaller: when debugging you may need to remove the commandbar too because VS 2005 and higher fire a new UISetup phase each time that you debug, so you get duplicated commandbars.

The temporary vs permanent approaches for commandbars is a nightmare for two reasons:

  • First, their own existence. A single approach would be much better. And the temporary one would be preferable. The reason for the permanent one is that for add-ins with a large number of commandbars and buttons, it takes less time to persist the UI on disk and retrieve it from there when launching VS than recreating the UI. I think that there aren’t many add-ins with lots of commandbars and buttons (certainly my MZ-Tools add-in is one with such large number of buttons, but I keep using the temporary approach). But if performance is a problem, then it is better to fix that rather than inventing a new approach. Some ideas for Microsoft to increase the performance of add-ins using the temporary approach are:

    • Provide a EnvDTE.Commands.Exist(commandName) method to test if a command exists or not (to create it only if it doesn’t exist). Currently you have to call the Item method which causes an (expensive) exception if the command doesn’t exist.
    • Provide a EnvDTE.AddInCommands collection that returns only the commands of add-ins, not the hundreds of commands of Visual Studio.
    • Make EnvDTE.Command.AddControl to behave as follows: if you are adding a button to a menu, set the CommandBarButton.Style to msoButtonIconAndCaption (VS already does this), but if you are adding it to a toolbar, set the CommandBarButton.Style to msoButtonIcon since it is more likely that style (without caption) on a toolbar. Currently VS defaults to msoButtonIconAndCaption also in this case, which means that after getting the CommandBarControl, you have to cast it to CommandBarButton and then change the Style property, which means that the button needs to be redrawn (a performance hit). I already reported this two years ago to no avail: Wrong default vsCommandStyle for CommandBarButtons created from add-ins. Even more, Visual Studio doesn’t work as supposed to do: Problems with ContextUIGUIDs and vsCommandDisabledFlagsValue in EnvDTE.Commands.AddNamedCommand (a bug yet to be acknowledged and fixed).
    • Simplify the way of getting transparent pictures for commands. The transparent color has been RGB=0,254,0 for long time which means that a color remapping must be performed. Hopefully this has been addressed in VS 2010 with support for 32-bit bitmaps with transparency in the alpha channel.
  • Second, the APIs are not consistent, which creates a lot of confusion. If both approaches need to exist, at least they would have to use the same methods with just one boolean parameter indicating if a commandbar is permanent or temporary. Currently you have:

    • CommandBars.Add to add temporary commandbars
    • CommandBar.Delete to remove temporary commandbars
    • Commands.AddCommandBar to add permanent commandbars (even if the CommandBars.Add method above has a Temporary parameter!)
    • Commands.RemoveCommandBar to remove permanent commandbars

Anyone can see that that mix of methods to add commandbars is bound to cause problems (why is there a AddCommandBar method in the Commands collection?) and certainly it is: the bug of devenv.exe /resetaddin can’t be fixed because the Commands.AddCommandBar method lacks a fundamental piece of information: the AddIn instance that is adding the commandbar. Without that information the IDE doesn’t know which add-in is the owner of a permanent commandbar and therefore can’t remove it.

More (good news) on Visual Studio 2010 getting rid of satellite DLLs for add-ins

In my last post Visual Studio 2010 getting rid of satellite DLLs for add-ins I mentioned that VS 2010 will provide two approaches to avoid satellite DLLs for command pictures of add-ins:

The first one was clear: command pictures will be able to be embedded in the own DLL of the add-in.

The second one was not so clear:

“Commands.AddNamedCommand2 will now support an IPicture”.

After that post I exchanged e-mails with Suzanne Hansen (Program Manager of Visual Studio Platform Shell Team) and Jeff Robison (the developer implementing the changes). While I thought that a new EnvDTE100.Commands3.AddNamedCommand3 would be added supporting managed System.Drawing.Bitmap or System.Drawing.Icon types, they explained me that the Bitmap parameter of the current EnvDTE80.Commands2.AddNamedCommand2 method is actually a Variant/Object, not an integer (as it happens with the old EnvDTE.Commands.AddNamedCommand method) and therefore it allows you to pass other types apart from an integer (denoting a numeric bitmap id). Jeff took advantage of this to accept an IPicture type without introducing a new AddNamedCommand method with a different signature.

The bad news was that, alas, IPicture is a native COM type, not a managed type, so developers of managed add-ins would have to use hacks such as OleCreatePictureIndirect or System.Windows.Forms.AxHost.GetIPictureDispFromPicture to convert a managed System.Drawing.Bitmap to a native COM IPicture or IPictureDisp. I was familiar with those techniques (see my article HOWTO: Creating custom pictures for Visual Studio .NET add-ins commands, buttons and toolwindows) and they were ugly to me, and prone to problems with transparency as happened in the past.

So, I suggested to make EnvDTE80.Commands2.AddNamedCommand2 to accept an IntPtr type that would denote the handle of a managed bitmap (System.Drawing.Bitmap.GetHBitmap). The EnvDTE.Window.SetTabPicture already accepts that happily to set the picture of a toolwindow.

They devoted some days to think about all that and a couple of days ago Suzanne informed me that Jeff was able to make EnvDTE80.Commands2.AddNamedCommand2 accept managed System.Drawing.Bitmap or System.Drawing.Icon apart from the native IPicture type added previously. This couldn’t be greater news. Not only you will be able to get rid of embedded bitmaps, so can also use icons if you are not comfortable with 32-bit bitmaps with alpha channel for transparency.

FWIW if you are developing a package and not an add-in:

“Jeff has also made a similar change for package authors – a new API, AddNamedCommand3, will be available that will also accept Bitmaps, Icons and IPictures.”

While these changes won’t be available in the next VS 2010 Beta 2, they will be in subsequent builds. It is also great that they did these changes so late in the VS 2010 development cycle. Usually when Beta 2 is reached it is “feature completed” and no changes such as those are allowed, just bug and performance fixes.

I am looking forward to test these new changes. At last Visual Studio will allow you to decide:

  • The way to provide custom pictures for add-ins:
    • Embedded bitmaps in satellite Dll
    • Embedded bitmaps in add-in Dll
    • Directly in the EnvDTE80.Commands2.AddNamedCommand2 method
  • The type of image to use:
    • 32-bit System.Drawing.Bitmap with alpha channel for transparency
    • System.Drawing.Icon (built-in transparency)

That plethora of choices together with the absence of COM stuff is what makes a good EnvDTE API for add-in developers.

Jeff and Suzanne, very good job!!

Microsoft fixing bug “Standard user unable to load/unload COM-based add-ins registered for all users with the VS Add-in Manager on Windows Vista”

Two years after I reported it, it seems that MS finally understood that this was a bug and I have been notified today that it is no longer closed as “By design” but as “Fixed”:

Standard user unable to load/unload COM-based add-ins registered for all users with the VS 2008 Add-in Manager on Windows Vista
http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=365846

This bug has plagued all of us developing add-ins with COM-registration (rather than .AddIn XML registration) for all users (not for current user) for backwards compatibility with VS.NET 2002 and/or 2003. Too bad that the fix comes so late that I doubt there will be a fix for VS 2008, only for VS 2010…but anyway, it will make VS 2010 a better product.

Visual Studio 2010 getting rid of satellite DLLs for add-ins. Oh..My..God :-)

After four years since I started pushing Microsoft to get rid of satellite DLLs to provide custom pictures for commands of add-ins, and then pushing again and then even again, and even through private channels I have as an MVP and even through private e-mails, all that to avoid the infamous official procedure to Display a Custom Icon on the Add-in Button, finally I have received official feedback through Microsoft Connect that VS 2010 will get rid of satellite DLLs for add-ins. Quote from one of the links above:

“I wanted to let you know that the following improvements to Visual Studio 2010 were made based on your feedback:

1)    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.
2)    Commands.AddNamedCommand2 will now support an IPicture.

QA is currently testing these changes, and I cannot confirm at this time if these changes will appear in the Beta 2 release of VS 2010.”

Item #1 is self-explanatory: when you pass a bitmap Id to the AddNamedCommand method, Visual Studio will use (as a last chance) the own dll of the add-in to find the embedded bitmap associated to that bitmap Id. My suggestion was to check the add-in dll first and if not found the satellite dll (to save time not locating the satellite dll with different cultures) but it seems that the order will be the opposite to not penalize add-ins that use satellite Dlls. Anyway this news is so great that any implementation detail doesn’t matter. So, at this point the only (minor) annoyance would be that you have to map Ids with bitmaps. That is, for each command picture you have to put the same Id number in two places: in the embedded picture and in the AddNamedCommand call.

Update (March 19, 2012): I have discovered two days ago that Visual Studio 2008 already supported embedding the bitmap in the dll of the add-in, as explained here.

But there seems to be more!:

I am not sure if item #2 means what it seems (too good to be true), but it could be that a new AddNamedCommand method will be added (I guess EnvDTE100.Commands3.AddNamedCommand3 because it can’t be added to the already shipped EnvDTE.Commands.AddNamedCommand or EnvDTE80.Commands2.AddNamedCommand2) and will receive a direct IPicture rather than a bitmap Id. Oh My God… 😛

UPDATE (Sep 6). See: More (good news) on Visual Studio 2010 getting rid of satellite DLLs for add-ins

This is such a milestone in Visual Studio extensibility with add-ins as when Visual Studio 2005 introduced CreateToolWindow2 to get rid of the need ActiveX C++ shim controls to host managed .NET usercontrols in add-in toolwindows. I was even thinking about doing some experiments to create a managed satellite DLL on the fly (dynamic) using System.Reflection.Emit and using the AssemblyResolve event to supply it to Visual Studio…the pain drives creative approaches…

Getting rid of satellite DLLs and even bitmaps Ids combined with the support for 32-bit bitmaps with transparency in the alpha channel for command pictures and even backwards compatibility using the old hack RGB=0,254,0 makes the VS 2010 release really great in this regard. The person responsible for making a reality all these very welcomed enhancements is Suzanne Hansen, Program Manager of the Visual Studio Platform Shell Team. Kudos to her and her team of developers and testers!. Thank you very much indeed 🙂 I am sure I am not the only one looking forward to test the VS 2010 bits that contain these changes.

Clarification on my previous post “Microsoft no longer fixing (small) bugs for VS 2010”

My post of a week ago “Microsoft no longer fixing (small) bugs for VS 2010, now focusing on stabilization and performance” has been commented (see the Comments section) by the DJ Park (C# IDE, Program Manager) explaining that the three bugs in the C# code model that I reported:

EnvDTE.CodeFunction.Parameters causes COM exception with add/remove methods of C# event

EnvDTE.CodeFunction.Attributes doesn’t return attributes for get/set property accessors in C#

EnvDTE.Project.CodeModel doesn’t retrieve attribute code elements in AssemblyInfo file for C#

and whose original answer was:

“We unfortunately won’t be able to address the limitation in the Project.CodeModel for the VS2010 release given that we’re purely focused on stabilization and performance but I’ve marked this bug down to be considered as we begin planning for the next release. In the meantime, I’m going to mark the bug as a “Wont Fix” but please feel free to re-activate if you have any further questions/comments.”

aren’t going to be fixed not because they are no longer fixing minor bugs on VS 2010 Beta 1 but because they are working in a new code model:

“Hey Carlos – Thanks for raising the thoughts/concerns.  I wanted to jump in to provide some more context on the bugs you mentioned.  I’d be happy to talk about this further if you’d like, so just let me know. (Quick note: I’m taking the excerpt below from a response I posted on InfoQ)

First of all, I apologize if my responses made it seem like we are no longer fixing minor issues on VS 2010. In fact, the main focus for the VS and .NET teams at this point in the product cycle is to fix bugs and do performance work in order to deliver a high quality release. To support this, we are making a conscious effort to focus on bugs and performance rather than new features or functionality. The decisions made around the EnvDTE bugs were targeted decisions and should not be taken as a broader indication that we are no longer fixing bugs.

To shed some light around the decisions regarding these C# code model bugs, the main reason we decided not to fix these issues is because we are making longer term investments in a public language model. This API will do a much better job than the existing Code Model in surfacing our compilers and will provide a richer representation of code. As a result, we decided to limit our investment in EnvDTE/CodeModel and treat regressions of existing functionality with higher priority. The bugs in question, while important, existed in previous releases.”

Since that second explanation was missing in the first response to my bugs in Microsoft Connect, that led me to the false conclusion of my post. The explanation is also now in a new fourth bug that I reported a couple of days ago:

EnvDTE.CodeElement.Name doesn’t include type placeholder for generics types or methods

Microsoft fixing issue of supporting RGB=0,254,0 for transparent color in command pictures also in VS 2010

The issue that I opened about VS 2010 Beta 1 command pictures supporting for the first time 32-bit bitmaps with alpha channel for transparency but not RGB=0,254,0 as in previous Visual Studio versions has been resolved by Microsoft for Beta 2:

Custom pictures in CommandBarButtons created by add-in don’t show a transparent background
http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=461192

So, while we’ll have to wait until we get the VS 2010 Beta 2 bits to test all this, Microsoft seems to have solved in a very acceptable way the nightmares of bitmap transparency for add-ins:

  • Command pictures will support 32-bit bitmaps with alpha channel (new way, first time) or RGB=0,254,0 for transparent color (old way)
  • Toolwindow pictures will support 32-bit bitmaps with alpha channel or RGB=255,0,255 for transparent color (old way).

Bottom line:

  • If your add-in only targets VS 2010 you can use 32-bit bitmaps with alpha channel for everything and forget about old hacks. While it seems that icons will not be supported (a long-time request from me) you can use transparent bitmaps.
  • If you have to support VS 2005/2008 yet, you can still use the old hacks (some special RGB color) in VS 2010 and keep a single bitmap set.

Now, if we could get rid of satellite DLLs

Microsoft no longer fixing (small) bugs for VS 2010, now focusing on stabilization and performance

Although VS 2010 Beta 2 hasn’t been released yet, Microsoft has stopped fixing the certainly minor bugs that I have reported in the last days about the C# file code model. Instead they are currently focused “on stabilizing and improving the performance of VS2010”. This is something that has happened in the past (I remember since VS 2005): once the Beta 2 is released no feature is changed and very few bugs are fixed (only the big ones that would prevent the release of the product), but I think that this time is worse, the facts are:

Too bad. I’m talking about minor bugs that should be easy to fix, not ones requiring architectural changes that I understand will be postponed.

I find quite stressing what will happen if the WPF commandbars are not fixed correctly for Beta 2, or new bugs appear with features that were not completed in Beta 1. I’d rather see no CTPs at all and a longer series of betas instead:

  • Beta 1: quite feature completed. Time to complete it and fix bugs.
  • Beta 2: feature completed. Time to fix bugs.
  • Beta 3: bugs fixed. Time to focus on stabilization and performance.
  • RC1, etc.

At least we would have two beta cycles to get bugs fixed.

All that said, I welcome the focus on the performance of the Visual Studio (the 2005 release was quite bad in this regard).

UPDATE: Microsoft clarified that this affects only to bugs in the code model because they are investing in a new code model. See Clarification on my previous post “Microsoft no longer fixing (small) bugs for VS 2010”

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