Visual Studio 2010, CLRs 4.0 and 2.0, and add-ins

More than a year ago I wrote about .NET Frameworks, CLRs and Visual Studio add-ins, where I explained that the new CLR 4.0 can coexist (for the first time in .NET) with a different CLR (2.0) in the same Windows process, and ended that post with the following question:

If I compile a Visual Studio add-in against CLR 2.0 (and .NET Framework 2.0 to be compatible with VS 2005, VS 2008 and VS 2010), when it is loaded within Visual Studio 2010 (which uses CLR 4.0), which CLR will use that add-in: CLR 2.0 or CLR 4.0?

At that time my answer (according to a test that I did) was CLR 4.0, but it was inconclusive because I was using a Community Technology Preview (CTP) version of Visual Studio 2010 and I didn’t know the switch in a .config file that controls that behavior.

These days I am struggling with a subject that indirectly got me back to that question. So, after some more investigation, today I have a definite answer to the question:

It depends on:

1) The useLegacyV2RuntimeActivationPolicy value in the <startup> section in the devenv.exe.config file

2) Whether the add-in is COM-based or XML-based (using .AddIn file)

And specifically (bottom line):

1) XML-based (using .AddIn file) add-ins compiled against CLR 2.0 use always CLR 4.0 when loaded in VS 2010.

2) COM-based (using COM-Interop) add-ins compiled against CLR 2.0 use:

2.1) CLR 4.0 if the useLegacyV2RuntimeActivationPolicy value of the <startup> section of devenv.exe.config is true. This value means that the runtime activation policy of .NET 2.0 will be used, which is to use the latest CLR available, so the COM-based add-in built using CLR 2.0 will use actually CLR 4.0.

2.2) CLR 2.0 if the useLegacyV2RuntimeActivationPolicy value of the <startup> section of devenv.exe.config is false. This value means that the runtime activation policy of .NET 2.0 will not be used, the new runtime activation policy of .NET 4.0 will be used instead, which is to use the CLR that the add-in was compiled against, so the COM-based add-in built using CLR 2.0 will use CLR 2.0.

This can be tested showing the value System.Environment.Version.ToString() when the add-in is loaded. Notice that while the default value (when omitted) of useLegacyV2RuntimeActivationPolicy is false, Visual Studio 2010 sets it to true in its devenv.exe.config file, which means that all add-ins (whether XML-based or COM-based) will use CLR 4.0.

The official documentation about the <startup> section and the useLegacyV2RuntimeActivationPolicy attribute is:

<startup> Element
http://msdn.microsoft.com/en-us/library/bbx34a2h.aspx

and Mark Miller (Marklio) explained it in full detail:

What is useLegacyV2RuntimeActivationPolicy for?
http://web.archive.org/web/20130128072944/http://www.marklio.com/marklio/PermaLink,guid,ecc34c3c-be44-4422-86b7-900900e451f9.aspx

The official documentation about In-Process side by side execution is here:

In-Process Side-by-Side Execution
http://msdn.microsoft.com/en-us/library/ee518876.aspx

which contains the following relevant paragraphs:

“Side-by-side hosting does not solve the compatibility problems that library developers face. A library that is directly loaded by an application — either through a direct reference or through an Assembly:Load call — continues to use the runtime of the AppDomain it is loaded into.”

and:

“In the past, managed COM components automatically ran using the latest version of the runtime installed on the computer. You can now execute COM components against the version of the runtime they were built with”

The strange case of MZ-Tools taking 10 seconds to load

Almost two weeks ago something strange started to happen on my laptop: the next version of MZ-Tools that I am working on was taking almost 10 seconds to load, while usually loads in 1 or 2 seconds. Since I was working on some other complex tasks (unit testing of add-ins, satellite DLL for custom pictures in international versions of Visual Studio, etc.), I didn’t devote time to troubleshoot this but as days passed finally three days ago I started to investigate.

At first I thought it was caused by some changes in the source code, such as handling the AppDomain.AssemblyResolve event to return the satellite DLL assembly, a required technique in international versions of Visual Studio (as I will blog about in a few days). But this was not the problem.

An intriguing thing was that the problem didn’t reproduce on another two computers of mine, nor on another partition of the same laptop with Windows 7 64-bit instead of Windows 7 32-bit. I created another user account on the partition where the problem reproduced and it happened too. So, it was not something user-specific but something machine-specific to the main partition and OS of my laptop (I was glad that this was the case and not a problem of the add-in).

I isolated the problem to the point where I measured that a single DTE.CommandBars.Add call to add a toolbar was taking 2 seconds (no surprise then that the whole add-in was taking 10 seconds). So I thought it could be some problem with the multiple products that install .NET / Visual Studio components, such as the own Visual Studio versions, their service packs, their security updates, but also Microsoft SQL Server (which installs .NET stuff) and Microsoft Office (which installs Visual Studio Tools for Applications). All that complicated with the fact that to do tests with international versions of Visual Studio I had both the English and Spanish versions installed.

So, I started to uninstall products, testing the load time after each uninstallation: the security packs, the service packs, SQL Server, Office, etc. etc. I even uninstalled the whole Visual Studio versions and reinstalled just one, to no avail: the add-in took still 2 seconds just to create a toolbar.

When I was resigned to format the partition and start from scratch hoping that that would solve the problem and maybe reinstalling products I could find the culprit, I did one last thing: to use Process Monitor to diagnose the problem. And I noticed a lot of disk access to the C:\Users\Carlos\AppData\Local\Microsoft\Windows\Temporary Internet Files location such as:

?FusionBindError!Category=NativeImage!exe=devenv.exe!name=EnvDTE80, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a

And when I saw the “FusionBind” term I remembered: a couple of weeks ago I needed to use the Assembly Bind Log Viewer (fuslogvw.exe) to diagnose the problems locating the satellite dll assembly in international versions of Visual Studio. I opened that tool and bingo! the trace was activated. As soon as I deactivated (note: you need to launch it with admin rights) the problem was solved. Somehow I forgot some day to turn it off.

Now I have a lot of products to reinstall, but I am happy that I didn’t have to reformat…  🙂

The strange case of the files pidpropsca.dll in C: and pidca.dll in C:\Program Files

I have been noticing for years the presence of two strange files in the file system of my computers:

  • pidpropsca.dll in C:
  • pidca.dll in C:\Program Files

Finally I decided today to investigate what they are, where they came from and more importantly, if I can delete them.

I thought it would be easy searching on the web. But both Google and Bing returned an incredible small list of results, and none of them was useful. The Pidpropsca.dll doesn’t have copyright but the other one, pidca.dll, belongs to Microsoft, and they were created in 2005 and 2006. No many clues here.

Then I used the Dependency Walker (depends.exe) utility to inspect the functions exported by those dlls. I found something more interesting:

  • pidca.dll exports the functions ValidateProductID and DllMain
  • pidpropsca.dll exports the functions SetAcademicProps and SetPidProps

It was the latter the one that gave me the clue, because “Academic” is something that Microsoft Visual Studio uses as one of the SKUs for editions. Also, I learned some days ago that to go from the Visual Studio 2010 Trial Edition that I got from Microsoft some days ago to the RTM release that was published on MSDN Subscriber Downloads some days later you need a “pid”,  which I guess it means “Product ID”. So, the dlls came from some Visual Studio version. I started searching the setups of all Visual Studio versions and I was lucky enough to find them at the fist version that I tried: the Visual Studio 2005 Team Edition for Database Professionals. This team edition came as a separate product after Visual Studio 2005, which originally only offered Team Edition for Developers, for Architects or for Testers, and the unified Team Suite. The setup folders of Visual Studio 2005 Team Edition for Database Professionals contain those two dlls.

I found later from this post of Quan To that “ca” stands for Crypto API and that during the installation of Visual Studio some data needs to be encrypted. Somehow the Visual Studio 2005 Team Suite and the Visual Studio 2008 Team Suite (which includes the Team Edition for Database Professionals) do all that stuff without using or leaving those two dlls in the file system. But Visual Studio 2005 Team Edition for Database Professionals uses and leaves them and since it was a separate product that I guess not many developers installed (I did because my MZ-Tools add-in supports it for some features), it is no surprise that there aren’t many search results on the web about those dlls.

MZ-Tools Articles Series: PRB: Unable to add buttons to toolbars of toolwindows of Visual Studio from an add-in

Today there was a question in the MSDN Forum for Visual Studio Extensibility (VSX) about adding a button to the toolbar (not to the context menu) of the Solution Explorer from a Visual Studio add-in. This is something that I am interested in too from time to time because I would like to move the “Collapse Projects” button of my MZ-Tools 6.0 add-in from the toolbar of the add-in to the more natural place, the toolbar of the Solution Explorer. I tried almost five years ago, when Visual Studio 2005 introduced EnvDTE80 and the new EnvDTE80.Window2 with its CommandBars property that gives you access to the toolbar of a toolwindow. Since add-ins are second-class citizens, this scenario was not tested by Microsoft and I found a bug that I reported:

COMException removing button from Solution Explorer commandbar
https://connect.microsoft.com/VisualStudio/feedback/details/113953/comexception-removing-button-from-solution-explorer-commandbar

The bug occurred actually removing the button, not adding it, but as Microsoft explained:

“It turns out the bug here is actually in the code to add the control, not delete it. The Solution Explorer toolbar has an internal flag indicating that modifications should not be allowed; CommandBarControl.Delete is properly respecting that flag (hence the error) but Command.AddControl is not.”

and when they finally fixed this problem (in VS 2008), it was not allowing add-ins to add buttons to the Solution Explorer toolbar, but rather throwing a System.UnauthorizedAccessException when you try to do it. Bottom line: add-ins are not allowed to add buttons to the Solution Explorer toolbar. VS 2010 is crystal-clear in its error message that this applies to other toolwindows too. I am not sure if this applies too to packages or only to add-ins.

The details and code to reproduce the problem are in my latest article:

PRB: Unable to add buttons to toolbars of toolwindows of Visual Studio from an add-in
http://www.mztools.com/articles/2010/MZ2010004.aspx

MZ-Tools Articles Series (update for VS 2010) INFO: Default .AddIn file locations for Visual Studio add-ins

I have updated once more one of the most popular articles that I have ever written to include information about Visual Studio 2010:

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

This is a problematic area in Visual Studio extensibility that is increasingly complicated with each new Visual Studio version or Windows version:

– Actual folder names changed between Windows XP and Windows Vista (fortunately Windows 7 doesn’t change them).

– Folders can be localized.

– If Visual Studio 2005 provided 5 folders (too many) where to search for .AddIn files, Visual Studio 2008 introduced a 6th one (%ALLUSERSDOCUMENTS%\Microsoft\MSEnvShared\AddIns), which actually never worked.

Visual Studio 2010 has fixed that bug with the 6th folder introduced by VS 2008, but Microsoft couldn’t resist to introduce a new (the 7th!) folder: %ALLUSERSPROFILE%\Microsoft Visual Studio\Addins (which at least works on its debut).

Furthermore, the long standing bug about the “Application Data” part hardcoded in one of the locations(%ALLUSERSPROFILE%\Application Data\Microsoft\MSEnvShared\AddIns) that I reported and that Microsoft reported that would be fixed, hasn’t been fixed. The fix would be a new folder where “Application Data” is not hardcoded (while keeping the old one to avoid breaking existing add-ins). If the new %ALLUSERSPROFILE%\Microsoft Visual Studio\Addins folder is the fix for this problem, it isn’t exactly a fix since it won’t fix add-ins whose setup use CSIDL_COMMON_APPDATA and on Windows XP only work in English.

Visual Studio and the International Settings, Language combobox

I was intrigued about where Visual Studio was getting the languages to fill the Language combobox in the Tools, Options dialog, Environment, International Settings section. After some investigation I discovered that the list is not stored in the registry or in some file. Visual Studio just scans the subfolders of the C:Program FilesMicrosoft Visual Studio <version>Common7IDE folder and checks which ones are LCID numbers!

So, you can copy the 1033 folder (which is English) and paste it as 3082 (which is Spanish) and you get the Spanish language in the combobox. Of course the user interface and everything else is in English because you didn’t get really the Spanish resources (that would require to install the full Spanish version of Visual Studio) but it is useful to test if the managed satellite dll for custom pictures will be loaded when the IDE is not in English (the problem that I am investigating now) without installing a full localized version (and its service pack and its security patches…)

The strange case of satellite DLL with culture ‘es-ES’ not found

The next version of my MZ-Tools add-in will target Visual Studio 2005, 2008 and 2010 so I can finally get rid of COM registration and native satellite DLLs and I can use a managed satellite DLL for custom pictures. I was using the “en-US” culture for the satellite DLL assembly and the same “en-US” name for the folder that contains it, and this was working fine for months using Visual Studio 2005/2008 in English on two computers, one with Spanish Windows XP and other with English Windows 7.

However, the other day, on the Spanish Windows XP computer loading the add-in in VS 2005 caused an FileNotFoundException saying that the satellite DLL with culture ‘es-ES’ (Spanish) was not found. In VS 2008 it worked fine. What the heck? That worked for months and anyway I thought that if some culture is not found, Windows, Visual Studio and whatever defaults to the English culture, but nope, using the Assembly Binding (Fushion) Log Viewer revealed that only the Spanish version was being searched for. What caused this problem?

It took me a while to discover the cause from the following facts:

  • The Windows OS was in Spanish
  • Visual Studio 2005 / 2008 were both in English
  • Visual Studio uses the default value “Same as Microsoft Windows” in the Tools, Options window, Environment, International Settings section, Language combobox.
  • If Visual Studio is not installed in the language of Windows, as it was the case, that setting is not honored and Visual Studio uses the language of the version that was installed, which was English.
  • In the VS 2005 that caused the problem, changing that setting to use “English” rather than “Same as Microsoft Windows” solved the problem. So, somehow, VS 2005 got the Spanish version too, although I didn’t install it.
  • When the “English” value was selected all project templates were fine, but when the “Same as Microsoft Windows” value was selected, most of the project templates disappeared, remaining only a few ones that gave me the clue that the product that brought the Spanish language to Visual Studio 2005 was a 3rd party product and Microsoft InfoPath 2007 and its Visual Studio Tools for Applications (VSTA) that I installed in Spanish some time ago. Since I was using VS 2008 most of the time, I didn’t notice this break until months later.

It happens that VSTA uses the Visual Studio 2005 Shell in integrated mode, so it affects the Visual Studio 2005 installation. However, it doesn’t seem to install all the resources in Spanish because the Visual Studio menus were in English, but the “Same as Microsoft Windows” setting was honored (using Spanish and causing the add-in to fail) and the project templates were filtered too.

The way for an add-in to know the language used by Visual Studio when the “Same as Microsoft Windows” setting is used is checking the EnvDTE.DTE.LocaleID property. I could have saved myself a few hours if I had included that piece of information in the exception report…

I am still trying to solve the problem of localized managed satellite DLLs (another ridiculous nightmare just to provide custom pictures) and when I find the solution I will update this article that currently fails in non-English Visual Studio versions:

HOWTO: Creating custom pictures for Visual Studio .NET add-ins commands,
buttons and toolwindows.
http://www.mztools.com/articles/2005/MZ2005007.aspx

I have posted too how to test add-ins in international versions of Visual Studio:

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

MZ-Tools Articles Series: HOWTO: Testing add-ins in localized versions of Visual Studio

The third article of the MZ-Tools Articles Series of this year is about testing add-ins in localized (international) versions of Visual Studio. It happens that most developers of the world are either native “English” or use English versions of Visual Studio and/or Windows, and therefore are not 100% aware of localizations that happen in the products. For example, many applications (even from Microsoft) hardcode “Application Data” rather than using the localized version of that folder that Windows uses. See for example this bug in Visual Studio:

Visual Studio hardcodes “Application Data” folder in the list of folders for .AddIn files
https://connect.microsoft.com/VisualStudio/feedback/details/466756/visual-studio-hardcodes-application-data-folder-in-the-list-of-folders-for-addin-files

which causes that setups of add-ins that call the Windows API that returns the actual (localized) name of that folder (the correct thing) actually fail to be recognized as add-ins in non-English versions of Windows, because VS won’t search for .AddIn files in the localized version of the folder (the VS 2008 SDK has an add-in with this problem, for example).

I am Spanish and in my case I use a mix of Spanish/English applications. For example, on same computers I have Windows and Office in Spanish while Visual Studio is in English. Taking into account that Office now offers Visual Studio Tools for Applications (VSTA) and Visual Studio Tools for Office (VSTO) I see issues caused by those mixes sometimes.

I posted a rant about localization issues in Visual Studio long time ago here:

MZ-Tools Articles Series: HOWTO: Get an OutputWindowPane to output some string from a Visual Studio add-in or macro
https://www.visualstudioextensibility.com/2008/08/13/mz-tools-articles-series-howto-get-an-outputwindowpane-to-output-some-string-from-a-visual-studio-add-in-or-macro

and this new article explains how to get multiple localized versions of Visual Studio on the same machine and which areas of an add-in should be tested:

HOWTO: Testing add-ins in localized versions of Visual Studio
http://www.mztools.com/articles/2010/MZ2010003.aspx

MZ-Tools Articles Series: HOWTO: Handle exceptions in a Visual Studio add-in

AFAIK, add-ins can’t use “global” exception handlers using AppDomain.UnhandledException, I think that because maybe all add-ins are loaded in the same AppDomain (not sure) and therefore it wouldn’t be suitable that an add-in handles the unhandled exception of another add-in… Anyway, I use exception handlers all around the code of my MZ-Tools add-in. Although I use a single method to treat the exceptions (showing an error to the user with a “Send Report” button, etc.), I made two errors that I am now (costly) fixing for next versions:

– The bug report misses important information about the IDE where the add-in causes the problem, including the IDE version. While in MZ-Tools 6.0 I use a different add-in assembly for each target IDE (so I can actually know the version), future versions of MZ-Tools will use a single add-in dll to target multiple IDEs.

– That method didn’t receive the DTE object and when I modified it to receive it, I realized that a lot of methods that were trapping exceptions didn’t have that DTE object to pass, because they were “helper” static (shared in C#) methods, so I had to do a lot of refactoring for every method to get access to the DTE object that the Connect class owns.

I have summarized what I consider good practices in this new article:

HOWTO: Handle exceptions in a Visual Studio add-in.
http://www.mztools.com/articles/2010/MZ2010002.aspx

MZ-Tools Articles Series: HOWTO: Locate the index of a CommandBarControl on a Commandbar to add a control or menu before or after it from a Visual Studio add-in.

After three whole months of procrastination about the MZ-Tools Articles Series and a lot of hesitation about continuing or giving up (I am continually struggling with day job, nights/weekends, family, spare time, some needed sport, this blog, the MSDN VSX forum, the MVP program, the MZ-Tools add-in, priorities balancing, etc. and even PS3 Top Spin 3 tennis gaming and a planned switch to Apple / iMac), it seems that today I found some desire to write a new (small) article about a question that appears from time to time in the forums:

HOWTO: Locate the index of a CommandBarControl on a Commandbar to add a control or menu before or after it from a Visual Studio add-in.
http://www.mztools.com/articles/2010/MZ2010001.aspx

More to come about internationalization issues in Visual Studio add-ins that I am facing these days…

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