Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Nota:
Este artículo es específico de .NET Framework. No se aplica a implementaciones más recientes de .NET, incluidas .NET 6 y versiones posteriores.
A partir de .NET Framework 4, puede usar el hospedaje en proceso paralelo para ejecutar varias versiones del Entorno de Ejecución de Lenguaje Común (CLR) en un único proceso. De forma predeterminada, los componentes COM administrados se ejecutan con la versión de .NET Framework con la que se compilaron, independientemente de la versión de .NET Framework que se carga para el proceso.
Contexto
.NET Framework siempre ha proporcionado hospedaje en paralelo para aplicaciones de código administrado, pero antes de .NET Framework 4, no proporcionó esa funcionalidad para los componentes COM administrados. En el pasado, los componentes COM administrados que se cargaron en un proceso se ejecutaron con la versión del entorno de ejecución que ya se cargó o con la versión instalada más reciente de .NET Framework. Si esta versión no era compatible con el componente COM, se produciría un error en el componente.
.NET Framework 4 proporciona un nuevo enfoque para el hospedaje en paralelo que garantiza lo siguiente:
La instalación de una nueva versión de .NET Framework no tiene ningún efecto en las aplicaciones existentes.
Las aplicaciones se ejecutan en la versión de .NET Framework con la que se compilaron. No usan la nueva versión de .NET Framework a menos que se le indique expresamente que lo haga. Sin embargo, es más fácil que las aplicaciones realicen la transición al uso de una nueva versión de .NET Framework.
Efectos en usuarios y desarrolladores
Usuarios finales y administradores del sistema. Estos usuarios ahora pueden tener una mayor confianza en que, al instalar una nueva versión del entorno de ejecución, ya sea de forma independiente o con una aplicación, no tendrá ningún impacto en sus equipos. Las aplicaciones existentes seguirán ejecutándose como lo hacían antes.
Desarrolladores de aplicaciones. El hospedaje en paralelo casi no tiene ningún efecto en los desarrolladores de aplicaciones. De forma predeterminada, las aplicaciones siempre se ejecutan con la versión de .NET Framework en la que se compilaron; esto no ha cambiado. Sin embargo, los desarrolladores pueden invalidar este comportamiento y dirigir la aplicación para que se ejecute en una versión más reciente de .NET Framework (consulte el escenario 2).
Desarrolladores y consumidores de bibliotecas. El hospedaje en paralelo no resuelve los problemas de compatibilidad a los que se enfrentan los desarrolladores de bibliotecas. Una biblioteca cargada directamente por una aplicación, ya sea a través de una referencia directa o de una llamada a Assembly.Load, sigue usando el tiempo de ejecución del AppDomain en el que se carga. Debe probar las bibliotecas en todas las versiones de .NET Framework que quiera admitir. Si una aplicación se compila con el entorno de ejecución de .NET Framework 4, pero incluye una biblioteca que se creó con un entorno de ejecución anterior, esa biblioteca también usará el entorno de ejecución de .NET Framework 4. Sin embargo, si tiene una aplicación que se creó con un entorno de ejecución anterior y una biblioteca compilada con .NET Framework 4, debe obligar a la aplicación a usar también .NET Framework 4 (consulte el escenario 3).
Desarrolladores de componentes COM administrados. En el pasado, los componentes COM administrados se ejecutaron automáticamente con la versión más reciente del entorno de ejecución instalado en el equipo. Ahora puede ejecutar componentes COM en la versión del entorno de ejecución con el que se compilaron.
Como se muestra en la tabla siguiente, los componentes compilados con .NET Framework versión 1.1 se pueden ejecutar en paralelo con los componentes de la versión 4, pero no se pueden ejecutar con los componentes de la versión 2.0, 3.0 o 3.5, ya que el hospedaje en paralelo no está disponible para esas versiones.
Versión de .NET Framework 1.1 2.0 - 3.5 4 1.1 No aplicable No Sí 2.0 - 3.5 No No aplicable Sí 4 Sí Sí No aplicable
Nota:
Las versiones 3.0 y 3.5 de .NET Framework se compilan incrementalmente en la versión 2.0 y no es necesario ejecutarse en paralelo. Son inherentemente la misma versión.
Escenarios comunes de hospedaje en paralelo
Escenario 1: Aplicación nativa que usa componentes COM creados con versiones anteriores de .NET Framework.
Versiones de .NET Framework instaladas: .NET Framework 4 y todas las demás versiones de .NET Framework usadas por los componentes COM.
Qué hacer: En este escenario, no haga nada. Los componentes COM se ejecutarán con la versión de .NET Framework con la que se registraron.
Escenario 2: Aplicación administrada compilada con .NET Framework 2.0 SP1 que prefiere ejecutar con .NET Framework 2.0, pero está dispuesta a ejecutarse en .NET Framework 4 si la versión 2.0 no está presente.
Versiones de .NET Framework instaladas: una versión anterior de .NET Framework y .NET Framework 4.
Qué hacer: en el archivo de configuración de la aplicación ubicado en el directorio de la aplicación, use el elemento > y el elemento > establecido de la siguiente manera:
<configuration> <startup > <supportedRuntime version="v2.0.50727" /> <supportedRuntime version="v4.0" /> </startup> </configuration>
Escenario 3: Aplicación nativa que usa componentes COM creados con versiones anteriores de .NET Framework que desea ejecutar con .NET Framework 4.
Versiones de .NET Framework instaladas: .NET Framework 4.
Qué hacer: en el archivo de configuración de la aplicación del directorio de la aplicación, use el elemento
<startup>
con el atributouseLegacyV2RuntimeActivationPolicy
establecido entrue
y el elemento<supportedRuntime>
configurado como se indica a continuación.<configuration> <startup useLegacyV2RuntimeActivationPolicy="true"> <supportedRuntime version="v4.0" /> </startup> </configuration>
Ejemplo
En el ejemplo siguiente se muestra un host COM no administrado que ejecuta un componente COM administrado mediante la versión de .NET Framework que el componente se compiló para su uso.
Para ejecutar el ejemplo siguiente, compile y registre el siguiente componente COM administrado mediante .NET Framework 3.5. Para registrar el componente, en el menú Proyecto , haga clic en Propiedades, haga clic en la pestaña Compilar y, a continuación, active la casilla Registrar para la interoperabilidad COM .
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
namespace BasicComObject
{
[ComVisible(true), Guid("9C99C4B5-CA54-4c58-8988-49B6811BA53B")]
public class MyObject : SimpleObjectModel.IPrintInfo
{
public MyObject()
{
}
public void PrintInfo()
{
Console.WriteLine("MyObject was activated in {0} runtime in:\n\tAppDomain {1}:{2}", System.Runtime.InteropServices.RuntimeEnvironment.GetSystemVersion(), AppDomain.CurrentDomain.Id, AppDomain.CurrentDomain.FriendlyName);
}
}
}
Compile la siguiente aplicación de C++ no administrada, que activa el objeto COM creado por el ejemplo anterior.
#include "stdafx.h"
#include <string>
#include <iostream>
#include <objbase.h>
#include <string.h>
#include <process.h>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
char input;
CoInitialize(NULL) ;
CLSID clsid;
HRESULT hr;
HRESULT clsidhr = CLSIDFromString(L"{9C99C4B5-CA54-4c58-8988-49B6811BA53B}",&clsid);
hr = -1;
if (FAILED(clsidhr))
{
printf("Failed to construct CLSID from String\n");
}
UUID id = __uuidof(IUnknown);
IUnknown * pUnk = NULL;
hr = ::CoCreateInstance(clsid,NULL,CLSCTX_INPROC_SERVER,id,(void **) &pUnk);
if (FAILED(hr))
{
printf("Failed CoCreateInstance\n");
}else
{
pUnk->AddRef();
printf("Succeeded\n");
}
DISPID dispid;
IDispatch* pPrintInfo;
pUnk->QueryInterface(IID_IDispatch, (void**)&pPrintInfo);
OLECHAR FAR* szMethod[1];
szMethod[0]=OLESTR("PrintInfo");
hr = pPrintInfo->GetIDsOfNames(IID_NULL,szMethod, 1, LOCALE_SYSTEM_DEFAULT, &dispid);
DISPPARAMS dispparams;
dispparams.cNamedArgs = 0;
dispparams.cArgs = 0;
VARIANTARG* pvarg = NULL;
EXCEPINFO * pexcepinfo = NULL;
WORD wFlags = DISPATCH_METHOD ;
;
LPVARIANT pvRet = NULL;
UINT * pnArgErr = NULL;
hr = pPrintInfo->Invoke(dispid,IID_NULL, LOCALE_USER_DEFAULT, wFlags,
&dispparams, pvRet, pexcepinfo, pnArgErr);
printf("Press Enter to exit");
scanf_s("%c",&input);
CoUninitialize();
return 0;
}