{"id":1363,"date":"2010-06-23T14:41:06","date_gmt":"2010-06-23T14:41:06","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/dotnet\/2010\/06\/23\/in-proc-sxs-and-migration-quick-start\/"},"modified":"2022-06-10T09:50:54","modified_gmt":"2022-06-10T16:50:54","slug":"in-proc-sxs-and-migration-quick-start","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/dotnet\/in-proc-sxs-and-migration-quick-start\/","title":{"rendered":"In-Proc SxS and Migration Quick Start"},"content":{"rendered":"<div class=\"WordSection1\">\n<div style=\"border-bottom: #4f81bd 1pt solid; border-right-style: none; border-top-style: none; border-left-style: none; padding: 0in 0in 4pt 0in;\"><\/div>\n<p class=\"MsoNormal\">This post is meant to help you understand what runtime in-process side-by-side is, how to think about it, how to use it, and how it affects application and component migration to the .NET 4 Runtime. This post is relevant to you if you use native runtime activation APIs, depend on specific runtime activation behaviors, or use mixed mode assemblies built with Visual Studio Managed Extensions for C++ v8 or v9, or if you\u2019re just interested in how we handle pre-.NET 4 and .NET 4 code coexisting on a machine.<\/p>\n<h2>The problem<\/h2>\n<p class=\"MsoNormal\">Prior to the .NET 4 Runtime, any given process was limited to loading only one runtime version, and was bound to that runtime for remainder of that process lifetime. In environments where independently authored components built and tested against different .NET Runtime versions can be loaded into a single process, this sometimes caused compatibility problems for the components that did not target the runtime that was loaded into the process.<\/p>\n<h2>Our Solution<\/h2>\n<p class=\"MsoNormal\">A new feature in the .NET 4 Runtime, \u201cin-process runtime side-by-side\u201d (or \u201cin-proc SxS\u201d for short) describes the ability to load more than one .NET Runtime version into the same process and have them run \u201cside by side\u201d. This ability to load multiple runtimes into the same process gives us with the ability to provide the highest level of compatibility possible for environments in which multiple independent managed components are loaded by, and communicate with, a native layer. COM is the biggest example of a native layer through which managed code must communicate, and this means that in an environment in which multiple independently-authored managed COM components are activated, each may be loaded into the runtime for which it was built and tested, which maximizes compatibility. The upcoming release of Visual Studio Tools for Office (VSTO) will take advantage of this by enabling all managed office <span class=\"SpellE\">addins<\/span> to be loaded within their targeted runtime.<\/p>\n<h2>Our Solution Is<i> Not\u2026<\/i><\/h2>\n<p class=\"MsoNormal\">In-proc SxS does not affect managed assembly loading, such as <span class=\"SpellE\">Assembly.Load<\/span> or loads due to assembly references \u2013 these scenarios continue to load the target assembly in the runtime where the load request was made. To take advantage of in-proc SxS, a managed component must be activated by a native host and interact with its environment through a native <span class=\"SpellE\">interop<\/span> layer such as COM <span class=\"SpellE\">interop<\/span> and P\/Invoke.<\/p>\n<p class=\"MsoNormal\">This may be easier to understand if you consider that that two runtimes loaded into a process operate completely independently; i.e., runtime X has no more knowledge about runtime Y than it does about any other native DLL loaded into a process. Each runtime has its own GC; each runtime creates, owns, and manages its own Application Domains (never the other way around), including Shared and Default domains for each; and each runtime interacts with unmanaged DLLs through <span class=\"SpellE\">interop<\/span> layers.<\/p>\n<h2>How to Think About In-Proc SxS<\/h2>\n<p class=\"MsoNormal\">Thinking about multiple runtimes in the same process without additional context isn\u2019t all that helpful; in fact, it just leads to more questions: \u201cHow and when does this happen?<span class=\"GramE\">\u201d;<\/span> and most importantly, \u201cDoes this affect me?\u201d<\/p>\n<h2>Does In-Proc SxS Affect Me?<\/h2>\n<p class=\"MsoNormal\">In-proc SxS was designed so that existing applications, components and libraries should be completely unaffected by an installation of the .NET 4 Framework &#8211; applications that were running against a pre-v4 framework will remain blissfully unaware of the install.<\/p>\n<p class=\"MsoNormal\">In addition, <span class=\"GramE\">migrating<\/span> a product to .NET 4 is unlikely to be affected by in-proc SxS if:<\/p>\n<p class=\"MsoListBulletCxSpFirst\"><span style=\"font-family: symbol;\">\u00b7\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/span>The product is a pure managed application;<\/p>\n<p class=\"MsoListBulletCxSpMiddle\"><span style=\"font-family: symbol;\">\u00b7\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/span>The product is a pure managed library; or<\/p>\n<p class=\"MsoListBulletCxSpLast\"><span style=\"font-family: symbol;\">\u00b7\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/span>The product is a pure managed COM component.<\/p>\n<p class=\"MsoNormal\">However, a product may be affected by in-proc SxS during migration if:<\/p>\n<p class=\"MsoListBulletCxSpFirst\"><span style=\"font-family: symbol;\">\u00b7\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/span>The product makes use of one or more deprecated APIs; or<\/p>\n<p class=\"MsoListBulletCxSpMiddle\"><span style=\"font-family: symbol;\">\u00b7\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/span>The product contains, or takes a dependency on, a <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/x0w2664k.aspx\">mixed mode assembly<\/a> built with Visual Studio Managed Extensions for C++ version 8 or 9.<\/p>\n<p>&nbsp;<\/p>\n<p class=\"MsoListBulletCxSpLast\">See the migration section below for more information.<\/p>\n<h2>Runtime Activation<\/h2>\n<p class=\"MsoNormal\" style=\"text-align: justify;\">For the small number of you who <i>may<\/i> be affected by in-proc SxS and need to gain a better understanding of it, the easiest way to understand how and where in-proc SxS fits into the managed world is to think about it as a <span class=\"MsoIntenseEmphasis\"><em>fundamental change to our runtime activation model<\/em><\/span>. <b><i>Runtime activation<\/i><\/b> describes the process by which the most appropriate runtime version is found, located, and loaded. A runtime request consists of a set of inputs, which can include (among others) an assembly (often the application\u2019s EXE), an <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/aa374182%28VS.85%29.aspx\">application configuration file<\/a> (often found next to the application\u2019s EXE), a version string, or any combination thereof, and runtime activation uses these inputs to determine the most suitable match from among the set of installed runtimes. Common examples are: managed EXE launch, <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ms686615%28VS.85%29.aspx\"><span class=\"SpellE\">CoCreateInstanceInstance<\/span><\/a> of COM-visible managed types, and <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/x0w2664k.aspx\">mixed-mode assemblies<\/a> loaded from native code.<\/p>\n<h3>Old Activation Model<\/h3>\n<p class=\"MsoNormal\">In prior releases, when in-proc SxS did not exist, our runtime activation policy had to take into consideration the reality that only one runtime could ever be loaded into a process. For self-contained managed applications the obvious choice was invariably the right one: activate the runtime that the application targets (derived either from metadata in the managed executable itself or from an application configuration file if one exists). And since virtually all managed application installers out there list the application\u2019s target runtime as a pre-requisite, the application could count on the target runtime being installed. Unfortunately, runtime activation was not always as clear cut in other important scenarios, the most prevalent of which is the activation of managed COM components. In such scenarios, the chosen policy has always been to activate in the latest installed runtime when no runtime has yet been loaded \u2013 a policy we call \u201cbind to latest.\u201d<\/p>\n<div style=\"margin-left: 0.2in; margin-right: 0.2in; border: #4f81bd 1pt solid; padding: 10pt;\">\n<p class=\"MsoBlockText\">Consider the following example to help understand why this policy was chosen for managed COM class activation. Let\u2019s say that a native application X exposes an extensibility mechanism through COM, and two authors separately write managed extensions A and B that target .NET Frameworks v1.1 and v2.0 respectively, and that application X and both extensions are installed on machine Z with both .NET Frameworks v1.1 and v2.0 installed.<\/p>\n<p class=\"MsoBlockText\">Say that, in the course of normal execution, application X <span class=\"SpellE\">CoCreateInstances<\/span> component A. In this case it may be tempting to use the same activation policy as that of managed <span class=\"SpellE\">executables<\/span> and pick the runtime that the component targets (v1.1). However, this choice would cause a later attempt to <span class=\"SpellE\">CoCreateInstance<\/span> component B to fail, because the .NET Runtime v1.1 (to which the process has been locked) cannot load a v2.0 assembly.<\/p>\n<p class=\"MsoBlockText\">To avoid this problem, the policy for managed COM component activation has always been to activate and load the component into the latest installed runtime, if a runtime has not yet been loaded. However, this policy created an impossibly high compatibility burden: we would need to provide 100% release-to-release compatibility, and to do so we would need to test every possible usage scenario for every managed application ever built on any previous .NET Runtime! So, while the entire .NET team will always set very high release-to-release compatibility requirements, we can all sleep a bit easier knowing that in-process side-by-side enables us to provide a much better compatibility model for our customers, insulating them from the small but inevitable accidental breaking changes that occur in a major product release.<\/p>\n<\/div>\n<h3>New Activation Model<\/h3>\n<p class=\"MsoNormal\">I\u2019m sure you\u2019ve guessed the fundamental change to our activation policy by now: <em><span class=\"MsoIntenseEmphasis\">starting with version 4, the .NET Runtime<\/span> <span class=\"MsoIntenseEmphasis\">activation policy may now load the most appropriate runtime version for a given activation request, without regard for the set of runtime version(s) that may already be loaded into the process<\/span><\/em>. The activation policy will no longer target the latest runtime on the machine as it did in previous versions (more details on this below). Again, there are some restrictions with when dealing with pre-v4 runtimes, but the above statement will hold true, without restriction, for all .NET Runtimes version 4 and higher.<\/p>\n<div style=\"margin-left: 0.2in; margin-right: 0.2in; border: #4f81bd 1pt solid; padding: 10pt;\">\n<p class=\"MsoBlockText\">Using the previous example, but with the small change that component A has been updated to target .NET 4, runtime activation policy is now free to activate component A in the v4 runtime and later activate component B in the v2 runtime. This provides the greatest compatibility by allowing components to run within their target runtime, without regard for the process environment into which it is loaded.<\/p>\n<\/div>\n<p class=\"MsoNormal\">Now that we\u2019ve covered the basics of the new in-proc SxS feature and activation model, let\u2019s look at the necessary considerations when <span class=\"GramE\">migrating<\/span> an application, component or library to .NET 4 from an earlier runtime.<\/p>\n<h2>Migration<\/h2>\n<div style=\"margin-left: 0.2in; margin-right: 0.2in; border: #4f81bd 1pt solid; padding: 10pt;\">\n<p class=\"MsoBlockText\">In the vast majority of cases it is simple to migrate an application to run on .NET Framework 4: if you are migrating an application at the source level, import your solution into Visual Studio 2010 and choose \u201c.NET Framework 4\u201d for the Target Framework in each project\u2019s properties page, then recompile; if you are migrating an application without recompiling, create or update the application configuration file to target .NET 4.For example, the following is the recommended &lt;startup&gt; section to use when migrating an application that targets .NET 3.5 to also target .NET 4:<\/p>\n<p class=\"MsoBlockText\"><span class=\"GramE\">&lt;?xml<\/span> version =&#8221;1.0&#8243;?&gt;<\/p>\n<p class=\"MsoBlockText\">&lt;<span class=\"GramE\">configuration<\/span>&gt;<\/p>\n<p class=\"MsoBlockText\">&lt;<span class=\"GramE\">startup<\/span>&gt;<\/p>\n<p class=\"MsoBlockText\">&lt;<span class=\"SpellE\">supportedRuntime<\/span> version=&#8221;v4.0&#8243;\/&gt;<\/p>\n<p class=\"MsoBlockText\">&lt;<span class=\"SpellE\"><span class=\"GramE\">supportedRuntime<\/span><\/span> version=&#8221;v2.0.50727&#8243;\/&gt;<\/p>\n<p class=\"MsoBlockText\">&lt;\/startup&gt;<\/p>\n<p class=\"MsoBlockText\">&lt;\/configuration&gt;<\/p>\n<p class=\"MsoBlockText\">Note that starting with .NET Framework 4, only a two-part version string is required, though three-part version strings are still accepted.<\/p>\n<\/div>\n<p class=\"MsoNormal\">A migration decision tree is provided later in this section.<\/p>\n<h2>Limitations and Exceptions<\/h2>\n<p class=\"MsoNormal\">When transitioning code originally targeting an in-proc-SxS-unaware runtime to an in-proc-SxS-aware runtime, some additional steps will need to be taken if your application contains one or more of the following:<\/p>\n<p class=\"MsoListParagraphCxSpFirst\" style=\"text-indent: -0.25in;\"><span style=\"font-family: symbol;\">\u00b7\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/span>calls to any of the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/aa964945.aspx\">hosting global static functions<\/a>, from native and\/or managed code;<\/p>\n<p class=\"MsoListParagraphCxSpMiddle\" style=\"text-indent: -0.25in;\"><span style=\"font-family: symbol;\">\u00b7\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/span>calls to any of the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/aa964998.aspx\">Strong Naming Global Static Functions<\/a>, from native and\/or managed code;<\/p>\n<p class=\"MsoListParagraphCxSpMiddle\" style=\"text-indent: -0.25in;\"><span style=\"font-family: symbol;\">\u00b7\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/span>native code that calls <span class=\"SpellE\">CoCreateInstance<\/span> using any of the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/aa964987.aspx\">hosting <span class=\"SpellE\">CoClasses<\/span><\/a> (<span class=\"SpellE\">CLSID_CorRuntimeHost<\/span>, <span class=\"SpellE\">CLSID_CLRRuntimeHost<\/span>, <span class=\"SpellE\">CLSID_TypeNameFactory<\/span>, or <span class=\"SpellE\">ComCallUnmarshal<\/span>), or is managed code that uses COM <span class=\"SpellE\">interop<\/span> to access interfaces implemented by any of the same CLSIDs;<\/p>\n<p class=\"MsoListParagraphCxSpMiddle\" style=\"text-indent: -0.25in;\"><span style=\"font-family: symbol;\">\u00b7\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/span>calls to <span class=\"SpellE\">CoCreateInstance<\/span>, from native code, using any of the metadata <span class=\"SpellE\">CoClasses<\/span> (<span class=\"SpellE\">CLSID_CorMetaDataDispenser<\/span>, or <span class=\"SpellE\">CLSID_CorMetaDataDispenserRuntime<\/span>), or managed code that uses COM <span class=\"SpellE\">interop<\/span> to access interfaces implemented by any of the same CLSIDs;<\/p>\n<p class=\"MsoListParagraphCxSpMiddle\" style=\"text-indent: -0.25in;\"><span style=\"font-family: symbol;\">\u00b7\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/span>calls to <span class=\"SpellE\">CoCreateInstance<\/span>, from native code, using the <span class=\"SpellE\">CoClass<\/span> of any COM-registered .NET Framework type;<\/p>\n<p class=\"MsoListParagraphCxSpMiddle\" style=\"text-indent: -0.25in;\"><span style=\"font-family: symbol;\">\u00b7\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/span>a managed COM component (in the binary migration case only);<\/p>\n<p class=\"MsoListParagraphCxSpLast\" style=\"text-indent: -0.25in;\"><span style=\"font-family: symbol;\">\u00b7\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/span><span class=\"GramE\">an<\/span> assembly produced with the Visual Studio Managed Extensions for C++ compiler (otherwise known as a <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/68td296t(VS.100).aspx\">managed C++ assembly<\/a>), or a dependency, either direct or indirect, on such an assembly.<\/p>\n<p class=\"MsoCaption\"><a name=\"_Ref248574332\"><\/a>Figure 1<\/p>\n<p class=\"MsoNormal\">The functionality in the above list was created for prior releases, and each lacks the ability to specify the target framework that is needed for in-proc SxS, and could not be retrofitted to do so. For the most part, all of these chose the same \u201cbind to latest\u201d activation policy as managed COM component activation.<\/p>\n<h3>Non-Impactful Install and \u201cLatest Runtime\u201d Activation Model<\/h3>\n<p class=\"MsoNormal\">Why am I even talking about our \u201cbind to latest\u201d activation policy? Well, there\u2019s a very good reason: one of the primary compatibility-related goals of the .NET 4 Framework is to ensure that its installation is non-impactful to pre-existing managed application or component. To achieve this, we have had to modify the \u201cbind to latest\u201d activation policy\u2019s semantics in the .NET 4 <span class=\"GramE\">release<\/span>.<\/p>\n<div style=\"margin-left: 0.2in; margin-right: 0.2in; border: #4f81bd 1pt solid; padding: 10pt;\">\n<p class=\"MsoBlockText\">The \u201cbind to latest\u201d runtime activation model kicks in when no target runtime version information is provided with the activation request, such as through a managed assembly\u2019s built-in version, a configuration file\u2019s list of &lt;<span class=\"SpellE\">supportedRuntime<\/span>&gt; entries, and\/or an explicit version string passed into any of the native hosting APIs that accept them. In these cases, in previous versions of the runtime, \u201cbind to latest\u201d activation would pick the very latest .NET Runtime installed on the machine. This is also the activation model used for managed COM classes built against pre-v4 runtimes, for precisely the reasons stated in the earlier example.<\/p>\n<\/div>\n<p class=\"MsoNormal\">Starting with the .NET 4 Runtime, this \u201cbind to latest\u201d activation policy has been modified so that, by default, it will only consider pre-v4 runtimes. By making this the default behavior, all pre-existing applications and components using this activation model will be unaffected by the installation of .NET 4.<\/p>\n<h3>Source Migration<\/h3>\n<p class=\"MsoNormal\">If you intend to retarget your application or component to .NET 4 and rebuild, and it uses any of the functionality listed above, then you need to migrate to the equivalent functionality provided in the new <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/dd380851%28VS.100%29.aspx\">.NET 4 Framework Hosting interfaces<\/a>:<\/p>\n<p class=\"MsoListParagraphCxSpFirst\" style=\"text-indent: -0.25in;\"><span style=\"font-family: symbol;\">\u00b7\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/span>for calls to any of the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/aa964945.aspx\">hosting global static functions<\/a>, use the corresponding methods provided by the new <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/dd233134%28VS.100%29.aspx\"><span class=\"SpellE\">ICLRMetaHost<\/span><\/a>, <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/dd233117%28VS.100%29.aspx\"><span class=\"SpellE\">ICLRMetaHostPolicy<\/span><\/a> and <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/dd233121%28VS.100%29.aspx\"><span class=\"SpellE\">ICLRRuntimeInfo<\/span><\/a> interfaces;<\/p>\n<p class=\"MsoListParagraphCxSpMiddle\" style=\"text-indent: -0.25in;\"><span style=\"font-family: symbol;\">\u00b7\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/span>for calls to any of the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/aa964998.aspx\">Strong Naming Global Static Functions<\/a>, use the corresponding methods provided by the new <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/dd409349%28VS.100%29.aspx\"><span class=\"SpellE\">ICLRStrongName<\/span><\/a> interface;<\/p>\n<p class=\"MsoListParagraphCxSpLast\" style=\"text-indent: -0.25in;\"><span style=\"font-family: symbol;\">\u00b7\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/span><span class=\"GramE\">for<\/span> instance creation of any of the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/aa964987.aspx\">hosting <span class=\"SpellE\">CoClasses<\/span><\/a>, metadata <span class=\"SpellE\">CoClasses<\/span>, or COM-visible Framework types, use <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/dd233135%28VS.100%29.aspx\"><span class=\"SpellE\">ICLRRuntimeInfo<\/span>::<span class=\"SpellE\">GetInterface<\/span><\/a>.<\/p>\n<p class=\"MsoCaption\">Figure 2<\/p>\n<p class=\"MsoNormal\">Each <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/dd233121%28VS.100%29.aspx\"><span class=\"SpellE\">ICLRRuntimeInfo<\/span><\/a> and <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/dd409349%28VS.100%29.aspx\"><span class=\"SpellE\">ICLRStrongName<\/span><\/a> interface instance targets a specific runtime, and each method exposes functionality specific to, or provided by, that targeted runtime.<\/p>\n<h3>Binary Migration<\/h3>\n<p class=\"MsoNormal\">If the preferred option of source migration and re-compilation is not possible, and the application or component also depends on any of the functionalities listed above, an application configuration extension is available to make migration possible in many cases. Adding this extension to the application\u2019s configuration file will modify the \u201cbind to latest\u201d policy to cause it to bind to the same runtime as the application itself. The extension takes the form of an attribute named useLegacyV2RuntimeActivationPolicy, to be placed in the &lt;startup&gt; element of an application configuration file. The attribute\u2019s valid values are \u201ctrue\u201d and \u201cfalse\u201d, of which \u201cfalse\u201d is the default. When set to \u201ctrue\u201d, this attribute instructs \u201cbind to latest\u201d runtime activation policy to consider all &lt;<span class=\"SpellE\">supportedRuntime<\/span>&gt; entries in the application configuration file; when set to false, the policy considers only those &lt;<span class=\"SpellE\">supportedRuntime<\/span>&gt; entries with a major version number of 2 or less. When a configuration file does not contain any &lt;<span class=\"SpellE\">supportedRuntime<\/span>&gt; entries (or a deprecated &lt;<span class=\"SpellE\">requiredRuntime<\/span>&gt; entry), then the version number contained in the executable image, which represents the runtime version against which the executable was built, is treated as an implicit &lt;<span class=\"SpellE\">supportedRuntime<\/span>&gt; entry (roughly speaking).<\/p>\n<div style=\"margin-left: 0.2in; margin-right: 0.2in; border: #4f81bd 1pt solid; padding: 10pt;\">\n<p class=\"MsoBlockText\">Thus, if you were <span class=\"GramE\">migrating<\/span> a .NET 3.5 application to .NET 4, your configuration file might look like this:<\/p>\n<p class=\"MsoBlockText\">&lt;<span class=\"GramE\">configuration<\/span>&gt;\n&lt;startup useLegacyV2RuntimeActivationPolicy=&#8221;true&#8221;&gt;\n&lt;<span class=\"SpellE\">supportedRuntime<\/span> version=&#8221;v4.0&#8243;\/&gt;\n&lt;\/startup&gt;\n&lt;\/configuration&gt;<\/p>\n<\/div>\n<p class=\"MsoCaption\">Figure 3<\/p>\n<h4>Managed COM Component<\/h4>\n<p class=\"MsoNormal\">To accommodate managed COM component authors (who in most cases cannot modify application configuration files), a separate mechanism is available: a semicolon delimited list of supported runtimes may be added to the component\u2019s InprocServer32 registration. Specifically, add the string value \u201c<span class=\"SpellE\">SupportedRuntimeVersions<\/span>\u201d to \u201cHKCRCLSID&lt;COM component <span class=\"SpellE\">clsid<\/span>&gt;InprocServer32&lt;COM component version&gt;\u201d.<\/p>\n<p class=\"MsoNormal\">It is important to note that <span class=\"MsoIntenseEmphasis\">if a managed COM component depends on any of the items in <\/span><span class=\"MsoIntenseEmphasis\"><span style=\"font-style: normal; color: windowtext; font-weight: normal;\"><span class=\"msoIns\"><ins cite=\"mailto:Abhishek%20Mondal\" datetime=\"2010-06-18T00:54\">Figure 1<\/ins><\/span><\/span><\/span><span class=\"MsoIntenseEmphasis\">, then it must be migrated at the source level<\/span>. This is because the COM component would need functionality equivalent to the new useLegacyV2RuntimeActivationPolicy configuration extension to work, which is a process-wide policy decision that must be made by the application author rather than by extensibility components.<\/p>\n<p class=\"MsoNormal\">If a managed COM component is activated through a <span class=\"SpellE\">reg<\/span>-free manifest (which cannot be extended to contain a <span class=\"SpellE\">SupportedRuntimes<\/span> entry), runtime activation will look for a configuration file next to the assembly containing the COM visible class. Note that a useLegacyV2RuntimeActivationPolicy entry will be ignored in this scenario.<\/p>\n<h4>Assemblies Built with Managed Extensions for Visual C++ Compiler<\/h4>\n<p class=\"MsoNormal\">There are two additional limitations with <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/68td296t(VS.100).aspx\">managed C++ assemblies<\/a>.<\/p>\n<p class=\"MsoNormal\">First, any dependency on a <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/x0w2664k.aspx\">mixed-mode assembly<\/a> built with a previous release of Visual C++ must be migrated using the useLegacyV2RuntimeActivationPolicy configuration file extension. This is because all such assemblies depend implicitly on the managed CRT, which in turn contains dependencies on functionality listed in Figure 1.This dependency has been removed in the upcoming release.<\/p>\n<p class=\"MsoNormal\">Second, all <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/x0w2664k.aspx\">mixed-mode<\/a> assemblies (including those built using this release of Visual C++) and all assemblies built with a previous release of Visual C++ may be loaded into at most one runtime per process, because they may contain process-global static image data that cannot be virtualized across runtimes, and\/or because they depend on a prior release of the managed CRT. This limitation is virtually identical in nature to the current limitation restricting these types of assemblies to no more than one application domain at once.<\/p>\n<h2>Migration Decision Tree<\/h2>\n<p class=\"MsoNormal\">Use the following decision tree to decide the correct migration path for your component in the most common scenarios.<\/p>\n<p class=\"MsoNormal\">\n<p class=\"MsoNormal\"><a href=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2010\/06\/2211.decision_tree_thumb.png\"><img decoding=\"async\" style=\"float: none; margin-left: auto; margin-right: auto; border: 0px;\" title=\"decision_tree\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2010\/06\/2211.decision_tree_thumb.png\" alt=\"decision_tree\" width=\"533\" height=\"571\" border=\"0\" \/><\/a><\/p>\n<p class=\"MsoNormal\" style=\"text-align: center;\" align=\"center\">\n<h2>Binary Migration Examples<\/h2>\n<h2><a name=\"_Application:_Target_v2\"><\/a>Application: Target v2 and v4<\/h2>\n<p class=\"MsoNormal\">Create an application configuration file with the following contents, where the highlighted portion is required only if the application depends on functionality from Figure 1:<\/p>\n<p class=\"MsoNoSpacing\" style=\"margin-left: 0.5in;\"><code><span style=\"font-size: 10pt;\">&lt;<span class=\"GramE\">configuration<\/span>&gt; <\/span>        <\/code><\/p>\n<p>&nbsp;<\/p>\n<p class=\"MsoNoSpacing\" style=\"margin-left: 0.5in;\"><code><span style=\"font-size: 10pt;\">&lt;startup <span style=\"background: yellow;\">useLegacyV2RuntimeActivationPolicy=\"true\"<\/span>&gt; <\/span>        <\/code><\/p>\n<p>&nbsp;<\/p>\n<p class=\"MsoNoSpacing\" style=\"margin-left: 0.5in;\"><code><span style=\"font-size: 10pt;\">&lt;<span class=\"SpellE\">supportedRuntime<\/span> version=\"v4.0\"\/&gt; <\/span>        <\/code><\/p>\n<p>&nbsp;<\/p>\n<p class=\"MsoNoSpacing\" style=\"margin-left: 0.5in;\"><code><span style=\"font-size: 10pt;\">&lt;<span class=\"SpellE\"><span class=\"GramE\">supportedRuntime<\/span><\/span> version=\"v2.0.50727\"\/&gt; <\/span>        <\/code><\/p>\n<p>&nbsp;<\/p>\n<p class=\"MsoNoSpacing\" style=\"margin-left: 0.5in;\"><code><span style=\"font-size: 10pt;\">&lt;\/startup&gt; <\/span>        <\/code><\/p>\n<p>&nbsp;<\/p>\n<p class=\"MsoNoSpacing\" style=\"margin-left: 0.5in;\"><code><span style=\"font-size: 10pt;\">&lt;\/configuration&gt; <\/span>        <\/code><\/p>\n<p>&nbsp;<\/p>\n<p class=\"MsoNoSpacing\"><code>        <\/code><\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p class=\"MsoNormal\"><code>As always, <\/code><span class=\"SpellE\"><code><span style=\"line-height: 115%; font-size: 10pt;\">supportedRuntime<\/span><\/code><\/span><code> entries are considered to be listed in decreasing preference; if the .NET 2 Runtime is preferred, the entries should be reversed.<b> <\/b>          <\/code><\/p>\n<p>&nbsp;<\/p>\n<h2>Application: Target v4 <span class=\"GramE\">Only<\/span><\/h2>\n<p class=\"MsoNormal\">Use the same application configuration file as above, but remove the v2-specific <span class=\"SpellE\"><code><span style=\"line-height: 115%; font-size: 10pt;\">supportedRuntime<\/span><\/code><\/span> entry.<\/p>\n<h2>Managed COM Component: Target v2 and v4<\/h2>\n<p class=\"MsoNormal\">If you authored a managed COM component built against the .NET 2 Runtime, with a CLSID of <code><span style=\"line-height: 115%; font-size: 10pt;\">{DFEEABC2-17FF-4ce6-B25B-A35F7A156C68}<\/span><\/code> and a version of <code><span style=\"line-height: 115%; font-size: 10pt;\">6.2.0.0<\/span><\/code>, and you wanted the component to run within either the .NET 2 Runtime or the .NET 4 Runtime (in that order of preference), the registry update (in <span class=\"SpellE\">RegEdit<\/span> syntax) would be:<\/p>\n<p class=\"MsoNoSpacing\" style=\"margin-left: 0.5in;\"><code><span style=\"font-size: 10pt;\">[HKCRCLSID{DFEEABC2-17FF-4ce6-B25B-A35F7A156C68}InprocServer326.2.0.0] <\/span>        <\/code><\/p>\n<p>&nbsp;<\/p>\n<p class=\"MsoNoSpacing\" style=\"margin-left: 0.5in;\"><code><span style=\"font-size: 10pt;\">\"<span class=\"SpellE\">SupportedRuntimeVersions<\/span>\"=\"v2.0.50727<span class=\"GramE\">;v4.0<\/span>\"<\/span><\/code><\/p>\n<p class=\"MsoNoSpacing\">\n<p>&nbsp;<\/p>\n<p class=\"MsoNormal\">If your component was registered without the assembly version portion of the registry key name, you would remove \u201c<code><span style=\"line-height: 115%; font-size: 10pt;\">6.2.0.0<\/span><\/code>\u201d from the key name.<\/p>\n<p class=\"MsoNormal\">Or, if your managed COM component is activated through registry-free COM, you would place an application configuration file (should we coin the term <i>component configuration file<\/i>?) next to the managed COM assembly with contents similar to the <a href=\"https:\/\/devblogs.microsoft.com\/dotnet\/in-proc-sxs-and-migration-quick-start\/#application-target-v2-and-v4\">example above<\/a> (without the highlighted portion, and with the <span class=\"SpellE\"><code><span style=\"line-height: 115%; font-size: 10pt;\">supportedRuntime<\/span><\/code><\/span> entries reversed).<\/p>\n<h2>Troubleshooting<\/h2>\n<h2>Instantiating Managed COM Components <span class=\"GramE\">From<\/span> Managed Code<\/h2>\n<p class=\"MsoNormal\">If your application instantiates and uses COM components through the .NET Runtime\u2019s managed <span class=\"SpellE\">interop<\/span> layer, and one of those COM components happens to be managed, then there is a small chance that after migrating your application you might run into an error similar to this:<\/p>\n<p class=\"MsoNoSpacing\" style=\"margin-left: 0.5in;\"><code><span style=\"font-size: 10pt;\">Error: Unable to cast COM object of type 'System.__<span class=\"SpellE\">ComObject<\/span>' to interface type '<i>X<\/i>'. This operation failed because the <span class=\"SpellE\">QueryInterface<\/span> call on the COM component for the interface with IID '{<i>12345678-1234-1234-1234-123456789012<\/i>}' failed due to the following error: No such interface supported (Exception from HRESULT: 0x80004002 (E_NOINTERFACE)).<b> <\/b>          <\/span><\/code><\/p>\n<p>&nbsp;<\/p>\n<p class=\"MsoNoSpacing\"><code><b>          <\/b><\/code><\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p class=\"MsoNormal\">This error can occur as a result of the following two combined conditions:<\/p>\n<p class=\"MsoListParagraphCxSpFirst\" style=\"text-indent: -0.25in;\"><code><b>1.\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/b><\/code><code>The managed COM component is registered against a different .NET Runtime version from that of the instantiating caller, causing it to be activated in another runtime than that of the instantiating caller.<\/code><code><b>           <\/b><\/code><\/p>\n<p>&nbsp;<\/p>\n<p class=\"MsoListParagraphCxSpLast\" style=\"text-indent: -0.25in;\"><code><b>2.\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/b><\/code><code>The interface is not marked with <\/code><span class=\"SpellE\"><code><span style=\"line-height: 115%; font-size: 10pt;\">System.Runtime.InteropServices.ComVisibleAttribute<\/span><\/code><\/span><code>, with a value of <\/code><code><span style=\"line-height: 115%; font-size: 10pt;\">true<\/span><\/code><code>.<\/code><code><b>           <\/b><\/code><\/p>\n<p>&nbsp;<\/p>\n<p class=\"MsoNormal\"><code>This scenario worked in the past because of a runtime optimization: when the .NET Runtime notices that a COM type it instantiates has a managed implementation, and that it was instantiated into the same Application Domain as the instantiating caller, it bypasses the managed <span class=\"SpellE\">interop<\/span> layer and returns to the caller the managed object itself. In prior .NET Framework releases (where in-proc SxS was not available), all managed COM types and their managed clients were commonly loaded into the same Application Domain, allowing the implementing managed object to be returned, and in turn allowing the interface cast succeed without being marked as <span class=\"SpellE\">ComVisible<\/span>.<b> <\/b>          <\/code><\/p>\n<p>&nbsp;<\/p>\n<p class=\"MsoNormal\"><span class=\"GramE\"><code>Migrating<\/code><\/span><code> an application can easily create condition 1; if the application also relies on condition 2 (which is much less common), then the above error will be encountered. There are a couple of solutions available:<b> <\/b>          <\/code><\/p>\n<p>&nbsp;<\/p>\n<p class=\"MsoListParagraphCxSpFirst\" style=\"text-indent: -0.25in;\"><code>1.\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/code><code>Get an updated version of the managed COM type that properly declares the interface as <span class=\"SpellE\">ComVisible<\/span>.           <\/code><\/p>\n<p>&nbsp;<\/p>\n<p class=\"MsoListParagraphCxSpLast\" style=\"text-indent: -0.25in;\">2.\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <code>Update the application configuration file to use the <\/code>useLegacyV2RuntimeActivationPolicy extension.<\/p>\n<h2>Loading Managed C++ Assemblies Built Against Previous .NET Runtime Versions<\/h2>\n<p class=\"MsoNormal\">Attempting to load a managed C++ assembly that was built with an earlier compiler into the .NET 4 Runtime when the application has not been configured with the useLegacyV2RuntimeActivationPolicy configuration file extension will result in the following error:<\/p>\n<p class=\"MsoNormal\" style=\"margin-left: 0.5in;\"><span class=\"SpellE\"><code><span style=\"line-height: 115%; font-size: 10pt;\">System.IO.FileLoadException<\/span><\/code><\/span><code><span style=\"line-height: 115%; font-size: 10pt;\">: Mixed mode assembly is built against version 'v2.0.50727' of the runtime and cannot be loaded in the 4.0 runtime without additional configuration information. <\/span>        <\/code><\/p>\n<p>&nbsp;<\/p>\n<p class=\"MsoNormal\">Note: the error is not 100% correct, as it specifies that only mixed mode assemblies are subject to this problem; it should say \u201cManaged C++\u201d instead of \u201cMixed mode\u201d, as managed C++ assemblies compiled with <code><span style=\"line-height: 115%; font-size: 10pt;\">\/<span class=\"SpellE\">clr:pure<\/span><\/span><\/code> will also encounter this error.<\/p>\n<p class=\"MsoNormal\">It is possible to correct this issue with either of the following:<\/p>\n<p class=\"MsoListParagraphCxSpFirst\" style=\"text-indent: -0.25in;\">1.\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Recompile the assembly with the .NET 4 managed C++ <span class=\"GramE\">compiler<\/span>.<\/p>\n<p class=\"MsoListParagraphCxSpLast\" style=\"text-indent: -0.25in;\">2.\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Update the application to use the useLegacyV2RuntimeActivationPolicy configuration file extension.<\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>This post is meant to help you understand what runtime in-process side-by-side is, how to think about it, how to use it, and how it affects application and component migration to the .NET 4 Runtime. This post is relevant to you if you use native runtime activation APIs, depend on specific runtime activation behaviors, or [&hellip;]<\/p>\n","protected":false},"author":342,"featured_media":58792,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[685],"tags":[],"class_list":["post-1363","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-dotnet"],"acf":[],"blog_post_summary":"<p>This post is meant to help you understand what runtime in-process side-by-side is, how to think about it, how to use it, and how it affects application and component migration to the .NET 4 Runtime. This post is relevant to you if you use native runtime activation APIs, depend on specific runtime activation behaviors, or [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/1363","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/users\/342"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/comments?post=1363"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/1363\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/media\/58792"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/media?parent=1363"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/categories?post=1363"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/tags?post=1363"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}