Category Archives: Add-Ins

Microsoft fixing the hardcoded, unlocalized “Application Data” subfolder when searching for .AddIn files

In the following article:

INFO: Default .AddIn file locations for Visual Studio add-ins
http://www.mztools.com/articles/2008/MZ2008001.aspx

I mentioned the problem with one of the locations (%ALLUSERSPROFILE%\Application Data\Microsoft\MSEnvShared\AddIns) that hardcodes “Application Data” subfolder, when it should be localized.

I reported the problem to Microsoft and it will be fixed in VS 2010 Beta 2:

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

All add-in developers using that location should pay attention because if Microsoft don’t follow my advice (mentioned in the bug report) of keeping the wrong location and adding a new, correct, one and they just change them instead, add-ins will be broken in international versions of Windows (because VS would no longer would search in the hardcoded path that many add-ins use). Stay tuned.

Usercontrols hosted in toolwindows still requiring ComVisible(True) attribute

Another scenario where a managed add-in for VS 2005 or higher still requires the ComVisible(True) attribute (apart from the Connect class that I blogged about in the last post) is when creating toolwindows with the EnvDTE80.Windows2.CreateToolWindow2 method: if you move the ComVisible(True) attribute from the AssemblyInfo file to the Connect class (which is actually the class that needs it) then the usercontrol class passed to the CreateToolWindow2 is not visible to COM and in these circumstances the CreateToolWindow2 method doesn’t return the created usercontrol as last parameter, and EnvDTE.Window.Object (which should return the usercontrol) is also null.

I had heard reports from people that said that when the usercontrol resided in another assembly rather than in the own add-in assembly, the CreateToolWindow2 didn’t return the instance of the usercontrol. Now the explanation is clear:  usercontrols in Windows Control Library projects have the ComVisible attribute set to false in the assemblyinfo file, while usercontrols in the add-in project have it set to true in the assemblyinfo file. So, the problem is not where the usercontrol resides, but whether the usercontrol is visible to COM or not.

Since managed add-ins should get rid of COM semantics, I have filed another bug report to Microsoft:

EnvDTE80.Windows2.CreateToolWindow2 doesn’t return in the last
parameter the hosted usercontrol if ComVisible attribute not set to true
https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=467084

Managed add-ins still requiring ComVisible(True) attribute

While add-ins for Visual Studio .NET 2002/2003 required COM registration (COM Interop) and registration for Visual Studio using the Windows registry, Visual Studio 2005 introduced XML-registration (.AddIn file) and removed the need for COM registration, both a big advance.

Then, one day, visiting the assemblyinfo.vb file that is not very much visited, you notice the following line:

<Assembly: ComVisible(True)>

and then you think that you can change it to:

<Assembly: ComVisible(False)>

At this point, if you try to load the add-in after this change you get an exception:

Error 80004002 (No such interface supported)

I blogged about this problem some months ago and today I have filed a bug report for MS to fix it:

Error 80004002 (No such interface supported) in add-in when ComVisible attribute is set to False
https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=467081

Note 1: while the add-in wizard sets the ComVisible attribute to True at assembly level, actually only the Connect class needs to have such attribute.

Note 2: since the ComVisible attribute uses a boolean parameter that can be set to true o false, one may wonder which is the behavior if the attribute is missing at all. The answer is in the MSDN docs: (public) types are visible to COM by default, the attribute is only needed to hide them to COM. So, if seeing <Assembly: ComVisible(True)> in your code bothers you too much, you can actually delete the line and the effect would be the same.

Two more reports about bugs in folders used by Visual Studio to locate .AddIn files

I thought that I had already reported these ones to Microsoft for VS 2008, but I don’t find the bug reports and anyway the bugs are still present in VS 2010 Beta 1:

Visual Studio hardcodes “Application Data” folder in the list of folders for .AddIn files
https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=466756

%ALLUSERSDOCUMENTS%\Microsoft\MSEnvShared\AddIns folder is not searched for add-ins
https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=466741

Wouldn’t be nice to know where a Visual Studio add-in is registered from?

Given that add-ins for Visual Studio can use COM-based registration or XML-based registration and that the first one uses two locations (HKEY_LOCAL_MACHINE / HKEY_CURRENT_USER) and the second one uses up to six folders by default (Tools, Options window, Environment, AddIn/Macros Security section), when developing and troubleshooting add-ins I often wonder where an add-in is registered from.

I have filed a suggestion report to get this info in the Add-In Manager of Visual Studio 2010:

Add information of add-in registration in Add-In Manager
https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=466762

You can vote for it if you would like to have that info too.

Call to action: please VOTE to get easy, custom, transparent, pictures for add-ins CommandbarButtons fixed forever

If you are subscribed to the RSS of this blog, chances are that you are an add-in developer, because despite its title, I don’t write very much about macros (nobody really uses them) and I don’t know about SDK packages, only a little about how to call SDK services from an add-in. So, if you are an add-in developer, you must know how difficult is to get custom, transparent pictures on add-in buttons.

I have tried with Microsoft to get this fixed in the last years publicly and privately to no avail, but I keep pushing 🙂 and now that they are changing the commandbars to WPF is the best chance to get this fixed forever. Just in case you haven’t tried yet, you can’t get transparent pictures in VS 2010 Beta 1, neither using native (C++) satellite DLLs nor using managed (.NET) satellite DLLs (I tried managed DLLs after opening the bug report).

The short story (call to action):

Go to this page and vote to get this problem fixed (I am thinking that if it gets some hundreds of votes maybe they will fix it):

Automation Model (EnvDTE) Enhancement: Accept .NET System.Drawing.Icon to set custom pictures in add-in commands and toolwindows
https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=336868

The long story (my last internal e-mail to Microsoft some days ago):

I would like to call the attention of all the people inside the Visual Studio Shell team that can make something to fix this problem that lasts 12 years now: it is very difficult to provide custom, transparent, pictures in buttons (CommandBarButton) created from add-ins:

– In VB5 (1997), VB6 and VBA you had to use the CopyFace/PasteFace methods to put custom pictures. The use of clipboard is causing problems today with remote desktop tools that monitor the clipboard.

– VS.NET 2002 forced to create a native (C++) resource library where the background color have to be almost green RGB = 0, 254, 0. The picture for ToolWindow.SetTabPicture have to use also that background color.

– VS 2005 allowed managed (VB.NET/C#) resource libraries, but you have to use also that color, or maybe magenta RGB=255,0,255.

– VS 2010 has again problem with transparency as I have reported here (neither almost green nor magenta works, at least with native satellite DLLs):

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

The problems are two:

– There should no need to use resource libraries.
– The transparency should be much easier.

A very simple solution that solves both problems is:

– To allow to use icons, rather than bitmaps. Icons do support transparency natively.
– To provide a EnvDTE100.Commands3.

AddNamedCommand3 method with this signature:Function
AddNamedCommand2(ByVal AddInInstance As EnvDTE.AddIn, ByVal Name As
String, ByVal ButtonText As String, ByVal Tooltip As String, Optional ByVal Icon As System.Drawing.Icon,
Optional ByRef ContextUIGUIDs As Object( ), Optional ByVal
vsCommandStatusValue As Integer = 3, Optional ByVal CommandStyleFlags
As Integer = 3, Optional ByVal ControlType As
EnvDTE80.vsCommandControlType = 2) As EnvDTE.Command.The same for the current Window.SetTabPicture(object): Make it to accept a Systen.Drawing.Icon with transparency.It would be up to the developer the decission to get this icon from a resource library, an embedded resource in the own add-in dll, a ImageList, a Picture control, a file on disk, an icon in memory, or whatever.

Then, internally in VS, make whatever you need to do with the icon:
transform it to a bitmap, transform the transparent color to green,
magenta or whatever, and paint it with transparent background.

Now that you are changing the commandbars to WPF and we are in Beta 1, it would be the best chance to get this fixed for good.

I have reported this twice through Microsoft Connect last years, to no avail:

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

If you still feel that the current implementation that you offer to people extending Visual Studio with add-ins to use custom, transparent pictures in their add-ins is not so bad, then be 100% fully coherent and modify the add-in wizard to create a solution with:

1) The add-in project
2) A satellite DLL project with a custom, transparent, picture

and make it work just pressing F5 to debug the add-in. If it is quite difficult, then it means that the current implementation is not so acceptable after all. But it is too easy to ignore the problem and make the add-in wizard to create only the add-in project, without the satellite DLL, and use the parameter values MsoButton=True, Bitmap=59 to use the smiley face from the Office bitmaps rather than using a custom picture.

With best regards,

Carlos Quintero

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

The lack of code model support inside methods

As you probably know, the code model (EnvDTE.ProjectItem.FileCodeModel) of the automation model of Visual Studio doesn’t provide information of variables, constants, statements, etc. inside a method. At most, you get the parameters of the method.

Eric Lippert explains in this post how the C# (or other compilers) work. It happens that they need two steps: the first one parses and resolves everything but the code inside the methods. Once the compiler knows about every possible type, the second step parses method bodies.

I am not sure if the file code model of EnvDTE relies on the internal .NET parsers or parses on its own but in any case it seems to follow the same two-step approach, but unfortunately without the second step (maybe for performance reasons, maybe because the file code model should parse on its own and MS never implemented it). Needless to say, to parse a method body can be quite complex and error prone (MS has whole teams for the development and testing of parsers). Hopefully we’ll have some day access to that information when the compiler is a service, as MS announced in the PDC 2008.