Known bugs in the new CommandBars of VS 2010 Beta 1

VS 2010 is changing the commandbars from the COM-based ones borrowed from Office to new WPF (.NET) ones, and the Beta 1 is the first public release showing this. The change is still under construction. For example, the “Tools”, “Customize…” menu is disabled for Beta 1 and you can’t change by hand (you can programmatically) a toolbar location from the top to the bottom, or to the left/right or make it floating as in previous versions. I am not sure if this is “by design” or a “not implemented yet” feature.

There are good news and bad news regarding the new CommandBar implementation.

The good news are that:

– Finally we may get rid of obscure COMExceptions that happened from time to time in the old implementation that I reported here, here and here.

– The object model is the same to to preserve compatibility with existing add-ins.

The bad news are:

– The object model is the same, confusing one, with lots of optional parameters, Object-typed parameters and so on. This is to preserve compatibility with existing add-ins, but there is not a new more clear model with strongly typed parameters and more intuitive. You can learn the model here: HOWTO: Adding buttons, commandbars and toolbars to Visual Studio .NET from an add-in

– The object model is not 100% backwards at run-time, some properties cause a “deprecated exception”. Not a big deal, but something to take into account.

– The new model still requires a satellite DLL and doesn’t accept icons yet to support transparency on custom buttons more easily, and guess what, you can’t get transparent buttons on Beta 1 (at least using a native resource dll, I have to test with a managed satellite DLL). I am strongly discussing this with Microsoft to see if they can fix this problem for good.

– There are quite a few bugs yet (some others that I reported were fixed for Beta 1). My list of known bugs is the following one, just in case you want to be aware of them or want to vote to get them fixed:

These ones are already acknowledged and will be fixed in the next build:

CommandBarButtons created by add-ins in context menus don’t appear

CommandBarPopup on toolbars doesn’t show arrow to indicate the dropdown

These ones are being investigated at the time of this writing:

Custom pictures in CommandBarButtons created by add-in don’t show a transparent background

EnvDTE.Command.Delete does not remove CommandBarButtons created from that command on Visual Studio commandbars

System.ArgumentNullException: “Value cannot be null.” getting CommandBar.Position from an add-in

“Object must be the same type as the enum” exception calling CommandBars.Add from an add-in

CommandBars.Item(“Tools”) causes exception rather than finding the commandbar.

CommandBarButton.TooltipText causes exceptions when getting or setting its value

Hopefully we can get them fixed, I have spent a lot of time this week isolating them to the minimal expression (my MZ-Tools add-in has a complex architecture to handle commands and buttons).

Interesting, challenging times regarding Visual Studio extensibility

If you have read about and played with Visual Studio 2010 Beta 1, you will have notice that we are under a major change, not so breaking in the external shell but internally. Visual Studio was born as a native, COM-based, C++ application and it seems that it has started a journey of several years towards a managed, .NET application. For the end user, the changes are not so huge: a more nice look and feel in commandbars, toolwindows or editor windows, a new extension manager to discover and install extensions, etc. but for developers extending Visual Studio, although in the long term this will be great, in the short term this is kind of a nightmare because of:

  • As it happens with new development, it will be plagued with bugs until all of them are fixed.
  • Some things are being “deprecated”. Have you noticed the “DeprecatedException” when using properties of the new CommandBars, CommandBarButtons, etc?
  • At the very least, you must test completely your extension (add-in, package) to see if it works with VS 2010, and either report bugs to MS or find workarounds to make it work.
  • You need to think carefully whether or how to leverage new extensibility features of VS, or keep using a common denominator. That is, for end-users it is great all the new improvements in each VS iteration, but as a developer of commercial or public extensions, you need to target many versions of VS. For example: do you use an common extension with .NET 2.0 for VS 2005, 2008 and 2010? Or do you create a separate version for VS 2010, maybe with .NET 4.0? Do you use the same setup for all? Or do you leverage the new Extension Manager for VS 2010?
  • Since add-ins are starting to be second-class citizens (with few development of new classes, methods and properties in EnvDTE* assemblies and missing or contradicting information about support in the new Extension Manager), do I start migrating to a package? Is it sensible to do it now when VS.NET 2003 should be still supported? Do I wait some years when package development (SDK) is truly easy?

When a type name is not the same that the same type name

Playing with Visual Studio 2010 Beta 1 and executing this statement:

toolBar = commandBars.Add(Name:=”My toolbar”, Position:=Microsoft.VisualStudio.CommandBars.MsoBarPosition.msoBarTop, Temporary:=True)

I have encountered this funny error:

“Object must be the same type as the enum. The type passed in was ‘Microsoft.VisualStudio.CommandBars.MsoBarPosition’; the enum type was ‘Microsoft.VisualStudio.CommandBars.MsoBarPosition’.”

What I guess that the error message is trying to say is that it was expecting a parameter with the type

‘Microsoft.VisualStudio.CommandBars.MsoBarPosition’

and it received a parameter with the type

‘Microsoft.VisualStudio.CommandBars.MsoBarPosition’

Since the type names are the same, why is it complaining?

I recalled that this is not the first time that I see this situation. The other one was the error “[found ref ‘EnvDTE.ProjectItem’][expected ref ‘EnvDTE.ProjectItem’] Unexpected type on the stack.” when using peverify.exe.

When this happens (the expected type name and the actual type name are the same but there is an error yet), it is because the types come from assemblies that are not the same. The assemblies may even have the same name, but they were loaded from different locations, and therefore are different instances and are different “things”.

In the case of the Microsoft.VisualStudio.CommandBars.MsoBarPosition, the problem happens because .NET 4.0 introduces a new feature named “No PIA – Primary Interop Assembly” which works embedding the actual used declarations of an (ActiveX) Interop reference in the assembly being built, so that the referenced PIA assembly doesn’t need to be deployed. And it happens that the add-in wizard creates a reference to Microsoft.VisualStudio.CommandBars.dll with the “Embed Interop Types” property set to True. Once compiled, the embedded types in the add-in assembly are not the same that those in the Microsoft.VisualStudio.CommandBars.dll PIA, and it seems that the commandBars.Add method (which receives Object types as parameters) do some checks about the passed types that fail unless you set the “Embed Interop Types” property to False.

You can vote to get this bug fixed here:

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

Visual Studio 2010 Beta 1 too slow on Virtual PC

I have spent the last days testing my MZ-Tools add-in with Visual Studio 2010 Beta 1 and there are a couple of things that I have noticed: the second one is that Beta 1 breaks a lot of things in the commandbars (I am reporting all the issues to Microsoft through Microsoft Connect and I will blog about the problems in the next days/weeks), but the first one is that Virtual PC 2007 (version 6.0.156.0) is too slow, painfully slow to debug add-ins. I am using Windows XP on a modern (desktop) computer (Core 2 Duo E8400, 3 GHz, 4 GB RAM) and I have assigned 2 GB to the virtual machine but the thing is so slow that on a second (laptop) computer at home I gave up and I created a second partition on the hard disk, which I also used to play with Windows 7 RC and it seems that it runs much better.

I have never been very fan about Virtual PC since I used it to test VS 2008 “Orcas” a couple of years ago and found some problems. Considering that Visual Studio is a monster in terms of performance (I know this is an early beta, but nonetheless), that today’s hard disks have enough space for another partition that you can even create within Windows without 3rd party tools, and that installing Windows takes less than an hour, I much prefer dual boot to test VS 2010 betas than Virtual PC.

New Microsoft Connect and MSDN forum for Visual Studio 2010 Beta 1 extensibility

As you likely know when reading this, Microsoft has released the Beta 1 of Visual Studio 2010. This release introduces a lot of internal and external changes, such as a WPF-based shell, a new WPF-based editor, and a new extension manager, etc. and therefore a lot of issues will arise with existing or new extensions (I certainly have a few of them regarding add-ins that I will blog in the next days).

You can report feedback to Microsoft about this release regarding extensibility using a couple of ways:

The Microsoft Connect web site:
https://connect.microsoft.com/VisualStudio/content/content.aspx?ContentID=12362

The new VS 2010 Beta 1 Extensibility Forum:
http://social.msdn.microsoft.com/Forums/en-US/vsxprerelease/threads

So, EnvDTE.Solution.AddXXX and EnvDTE.ProjectItems.AddXXX methods return Nothing “by design”…

These days I am working on some Visual Studio automation to perform unit testing against some features of my MZ-Tools add-in. I know I should have done this long time ago, but I never found the time or willingness to do it until last week. And since then I am thrilled because while the cost of writing code to test an application can make unit testing arguable, if you have to test your add-in against four Visual Studio versions and soon five versions, it clearly pays off, specially if you are a perfectionist like me that do a lot of code refactoring (with the risk of breaking something) to get better code.

Unit testing add-ins poses some challenges since the add-in DLL must be hosted inside the VS IDE, likely its classes and methods are not public, the add-in needs a solution to be tested against it, etc. I will try to blog about all this in a few weeks when I have time again (I’ll travel to Japan tomorrow for two weeks) but for now suffice to say that I am automating Visual Studio to make the tests to create the (disposable) solution, projects, files and sample code that they will use, rather than depending on already created solutions (which should be in different format for each VS version). And one thing that I have found while automating Visual Studio is that the EnvDTE.Solution.AddFromTemplate and EnvDTE.ProjectItems.AddFromTemplate methods return null (Nothing in VB.NET) in VS 2005 or higher rather than the created EnvDTE.Project or EnvDTE.ProjectItem.

I hardly remembered that I read about this in the Working with Visual Studio 2005 book (which despite its misleading name is about creating add-ins). Checking the MSDN documentation yesterday I saw that Ed Dore (from MS) explained it in the Community Content section, and when I was about to write a MZ-Tools article about it, I have found that I already had one about this back in 2006:

PRB: Solution.AddXXX and ProjectItems.AddXXX methods return Nothing (null)
http://www.mztools.com/Articles/2006/MZ2006019.aspx

Needless to say, I think it is a pity this loss of functionality introduced by VS 2005 due to changes in the wizard/templates mechanism. If only one file is created, it should return it. If more than one file is created, it should return the main one (such as Form1.cs rather than Form1.Designer.cs). Or if all that is not possible with the exising methods, provide new AddFromTemplate2 methods that return a collection of added files. All that is better than returning nothing and forcing the developer to guess the added file iterating the collection or using the OnItemAdded event.

BTW, using the AddFromTemplate methods is very tricky across Visual Studio versions and across languages in the same version. I will try to write an entry about this on the plane to post when I am online again 🙂

MZ-Tools Articles Series: HOWTO: Getting information about Visual Studio windows from an add-in

A common question about Visual Studio windows is how to get information about them. It happens that the automation model uses the same class (EnvDTE.Window) for documents and toolwindows, so the first question is how to differentiate both. And once you know that it is a toolwindow, which one is it? It happens that you have the Kind property, but also the hidden Type property. And the Guids that identify toolwindows types are scattered among two assemblies (EnvDTE and EnvDTE80), with different class names, and even in different constant groups in the same class. My new article tries to explain all this:

HOWTO: Getting information about Visual Studio windows from an add-in
http://www.mztools.com/articles/2009/MZ2009010.aspx

MZ-Tools Articles Series: HOWTO: Understanding Visual Studio behavior when an add-in tries to edit a read-only file

When using Visual Basic 6.0, if you tried to edit a read-only file (a checked-in file under source control, or a “by hand” read-only file), you got an error messagebox and that was all. However, when using Visual Studio .NET, if you try to edit a read-only file, a lot of things can happen depending on several dialog prompts and configurable settings. Even things that IMHO should not be allowed by Visual Studio, such as allowing editing a read-only file and deferring the problem of what to do with the changes when trying to save it. When writing an add-in that tries to modify a file, you should take all them into account:

HOWTO: Understanding Visual Studio behavior when an add-in tries to edit a read-only file
http://www.mztools.com/articles/2009/MZ2009009.aspx

MZ-Tools Articles Series: HOWTO Launch a process with admin rights from a Visual Studio 2008 add-in on Windows Vista

On Windows Vista with the User Account Control (UAC) feature enabled, processes that need to run with admin rights prompt the user for consent (either with a “OK” action if the user is already an admin running as standard user, or with an admin password request if the user is not an admin at all).

While Visual Studio .NET 2002, 2003 and 2005 need to run as admin (so you get the consent prompt when launching them on Windows Vista), VS 2008 was designed to run without admin rights (so you don’t get a consent prompt when running on Windows Vista). For that reason, you need to carefully design your add-in to work correctly on Windows Vista without requiring admin rights, as I explained in the article HOWTO: Design a Visual Studio add-in to install and run on Windows Vista.

But what happens if your add-in running inside VS 2008 on Windows Vista needs to launch a process that requires admin rights? For example, if it needs to launch regedit.exe? It will happen that the call to System.Diagnostics.Process.Start(…) will fail because the devenv.exe process of VS 2008 is running without admin rights. I recently found this situation for my MZ-Tools add-in and fortunately you can get easily the user’s consent with this code (VB.NET) using the “runas” verb:

HOWTO: Launch a process with admin rights from a Visual Studio 2008 add-in on Windows Vista
http://www.mztools.com/articles/2009/MZ2009007.aspx

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