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”