Compartir a través de


Registration-Free Activación de . componentes deNET-Based: un tutorial

 

Steve White
Soporte técnico Premier para desarrolladores, Microsoft UK

Leslie Muller
Global IT Research & Development, Credit Suisse First Boston

Julio de 2005

Resumen: Microsoft Platform SDK realiza un excelente trabajo de documentar los temas de aplicaciones aisladas y ensamblados en paralelo. Sin embargo, no todos equivalen a este tema con el de activación sin registro de componentes COM. COM sin registro es una característica de plataforma de gran interés para las empresas con servidores bloqueados y aplicaciones aisladas en infraestructuras compartidas. En este artículo se explica un ejemplo de trabajo de la activación sin registro de un componente basado en .NET Framework por parte de clientes nativos a través de la interoperabilidad COM. (11 páginas impresas)

Se aplica a:
   Microsoft Windows Server 2003
   Microsoft Windows XP Service Pack 2
   Microsoft .NET Framework versión 1.1
   Microsoft Visual Studio .NET 2003
   Microsoft Visual Basic 6.0

Descargue el ejemplo que acompaña a este artículo, MSDNRegFreeNet.msi.

contenido de

Introducción
terminología com de Registration-Free
Ejecución del ejemplo
Creación de un ensamblado de .NET como servidor COM
Compilación del cliente
activación de Registration-Free
Solución de problemas
Conclusión
Lectura adicional

Introducción

COM sin registro es un mecanismo disponible en las plataformas Microsoft Windows XP (SP2 para componentes basados en .NET Framework) y Microsoft Windows Server 2003. Como sugiere el nombre, el mecanismo permite una implementación sencilla (por ejemplo, XCOPY) de componentes COM en una máquina sin necesidad de registrarlos.

En las plataformas de destino, una de las fases de inicialización de un proceso y sus módulos dependientes es cargar los archivos de manifiesto de asociados en una estructura de memoria denominada contexto de activación . En ausencia de entradas del Registro correspondientes, es un contexto de activación que proporciona la información de enlace y activación que necesita el entorno de ejecución COM. No se requiere ningún código especial en el servidor COM o en el cliente, a menos que decida evitar el uso de archivos mediante la creación de contextos de activación usted mismo mediante la API de contexto de activación de .

En este tutorial compilaré un ensamblado de .NET simple y lo consumiré, tanto registrados como no registrados, desde clientes COM nativos escritos en Visual C++ y Visual Basic 6.0. Puede descargar el código fuente y los ejemplos y verlos en acción inmediatamente o puede seguirlo junto con el tutorial y compilarlos paso a paso.

terminología com de Registration-Free

Cualquier persona que esté familiarizado con la tecnología .NET se acostumbrará al término ensamblado que significa un conjunto de uno o varios módulos implementados, denominados y versionados como unidad, con un módulo que contiene un manifiesto de que define el conjunto. En COM sin registro, los términos ensamblado y manifiesto se toman prestados para ideas similares en concepto, pero no idénticas a sus homólogos de .NET.

COM sin registro usa ensamblado para significar un conjunto de uno o varios módulos PE (es decir, nativos o administrados) implementados, denominados y versionados como una unidad. COM sin registro usa manifiesto para hacer referencia a archivos de texto con la extensión .manifest que contiene XML, que define la identidad de un ensamblado de (manifiesto de ensamblado) junto con los detalles de enlace y activación de sus clases, o define la identidad de una aplicación (manifiesto de aplicación) junto con una o varias referencias de identidad de ensamblado. Un archivo de manifiesto de ensamblado se denomina para el ensamblado y se denomina un archivo de manifiesto de aplicación para la aplicación.

El término ensamblados en paralelo (SxS) hace referencia a la configuración de diferentes versiones del mismo componente COM, a través de archivos de manifiesto, para que se puedan cargar simultáneamente mediante subprocesos diferentes sin necesidad de registrarse. SxS habilita y es sinónimo de com sin registro.

Ejecución del ejemplo

Después de descargar y extraer el código de ejemplo, encontrará una carpeta denominada \deployed. Aquí está la versión de Visual C++ de la aplicación cliente (client.exe), su manifiesto (client.exe.manifest) y la versión de C# del servidor COM (SideBySide.dll). Continúe y ejecute client.exe. El resultado esperado es que client.exe activará una instancia de SideBySideClass (implementada en SideBySide.dll) y mostrará el resultado de llamar a su método Version que debería ser similar a "1.0.0-C#".

Creación de un ensamblado de .NET como servidor COM

Paso 1

En Visual Studio .NET 2003 crear un nuevo de C# o proyecto de biblioteca de clases de Visual Basic .NET y llamarlo SideBySide. Quite el AssemblyInfo. [cs/vb] archivo del proyecto e implemente una clase como se indica a continuación:

Código de C#

using System;
using System.Reflection;
using System.Runtime.InteropServices;

[assembly: AssemblyVersion("1.0.0.0")]
[assembly: Guid("[LIBID_SideBySide]")]

namespace SideBySide
{
   [Guid("[IID_ISideBySideClass]")]
   public interface ISideBySideClass
   {
      string Version();
   }

   [Guid("[CLSID_SideBySideClass]")]
   public class SideBySideClass : ISideBySideClass
   {
      public string Version()
      {
         return "1.0.0-C#";
      }
   }
}

Código de .NET de Visual Basic

Imports System
Imports System.Reflection
Imports System.Runtime.InteropServices

<Assembly: AssemblyVersion("1.0.0.0")> 
<Assembly: Guid("[LIBID_SideBySide]")>

<Guid("[IID_ISideBySideClass]")> _
Public Interface ISideBySideClass
    Function Version() As String
End Interface

<Guid("[CLSID_SideBySideClass]")> _
Public Class SideBySideClass
    Implements ISideBySideClass
    Function Version() As String Implements ISideBySideClass.Version
        Version = "1.0.0-VB.NET"
    End Function
End Class

He escrito los valores GUID, que serán específicos del proyecto, en forma de marcadores de posición. Deberá usar la herramienta guidgen de para generar GUID únicos que serán los valores respectivos que voy a tener en cuenta cuando use posteriormente los marcadores de posición.

Paso 2

Para que se genere y registre una biblioteca de tipos en tiempo de compilación, establezca el valor Registrar para interoperabilidad COM en true.

Paso 3

Genere una compilación de versión y copie SideBySide.dll en \deployed.

Compilación del cliente

El siguiente paso consiste en compilar el cliente y, para este tutorial, tiene la opción de compilar una visual C++ o un cliente de visual Basic 6.0.

Paso 4 (opción A: Visual C++)

Cree un nuevo proyecto de consola Win32 de Visual C++ denominado cliente en una carpeta del mismo nivel relativa a la carpeta del proyecto de SideBySide. En la asistente para aplicaciones Win32, en la pestaña Configuración de la aplicación de , active la casilla Agregar compatibilidad con ATL.

Edite stdafx.h y agregue la siguiente línea en la parte superior del archivo, inmediatamente después del #pragma once:

#define _WIN32_DCOM

Además, en stdafx.h agregue la siguiente línea en la parte inferior del archivo:

import "[path]\SideBySide.tlb" no_namespace

Aquí, [ruta] debe ser la ruta de acceso relativa a la biblioteca de tipos que se generó al compilar el ensamblado sideBySide de . Esta ruta de acceso suele variar en función de si ha elegido un proyecto de .NET de C# o de Visual Basic en el paso 1.

Reemplace el contenido de client.cpp por este código:

#include "stdafx.h"
#include <iostream>
using namespace std;

void ErrorDescription(HRESULT hr)
{
    TCHAR* szErrMsg;
    if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|
      FORMAT_MESSAGE_FROM_SYSTEM, 
      NULL, hr, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 
      (LPTSTR)&szErrMsg, 0, NULL) != 0)
   {
        cout << szErrMsg << endl;
        LocalFree(szErrMsg);
    }
   else
        cout << "Could not find a description for error 0x" 
           << hex << hr << dec << endl;
}

int _tmain(int argc, _TCHAR* argv[])
{
   CoInitializeEx(0, COINIT_MULTITHREADED);

   {
      ISideBySideClassPtr ptr;
      HRESULT hr = 
              ptr.CreateInstance(__uuidof(SideBySideClass));
      if (SUCCEEDED(hr))
      {
         cout << ptr->Version() << endl;
      }
      ErrorDescription(hr);

      char c;
      cin >> c;
   }

   CoUninitialize();

   return 0;
}

Genere una compilación de versión y copie \release\client.exe en \deployed.

Paso 4 (opción B: Visual Basic 6.0)

Cree un nuevo proyecto exe estándar de Visual Basic 6.0. En el Explorador de proyectos seleccione el nodo Project1 y, en la ventana propiedades de , cambie su nombre a cliente. Elegir archivo | Guarde Project As y guarde el archivo de formulario y el archivo de proyecto en una carpeta del mismo nivel relativa a la carpeta del proyecto SideBySide. Elegir proyecto de | Referencias, active la casilla situada junto a SideBySide y elija Aceptar.

Haga doble clic en el formulario principal del diseñador de formularios y pegue el código siguiente dentro de Sub Form_Load():

    Dim obj As New SideBySideClass
    Dim isxs As SideBySide.ISideBySideClass
    Set isxs = obj
    MsgBox isxs.Version()

Elegir archivo | Haga client.exe... y vaya a la carpeta \deployed y, a continuación, elija Aceptar.

Paso 5

En la actualidad, la carpeta \deployed debe contener, aparte de algunos archivos intermedios, solo client.exe y SideBySide.dll; y este último habrá sido registrado por su proceso de compilación. Para comprobar que el servidor y el cliente funcionan conjuntamente en estas circunstancias normales, ejecute \deployed\client.exe y anote la salida esperada "1.0.0-C#" o "1.0.0-VB.NET".

Paso 6

Este tutorial trata sobre COM sin registro, por lo que ahora es necesario anular el registro del ensamblado SideBySide. En un símbolo del sistema de Visual Studio 2003, vaya a la carpeta \de \deployed y ejecute el comando: regasm /u SideBySide.dll.

Paso 7

Para ver qué efecto ha tenido el paso anterior, vuelva a ejecutar \deployed\client.exe y verá el mensaje "Clase no registrada" o "Error en tiempo de ejecución '429': el componente ActiveX no puede crear el objeto". En esta fase, hemos frustrado que el tiempo de ejecución com encuentre la información que necesita en el registro, pero aún tenemos que hacer que la información esté disponible por medios alternativos. Lo solucionaremos en los pasos siguientes.

activación de Registration-Free

Paso 8

En la carpeta \deployed, cree un archivo de manifiesto de aplicación (un archivo de texto) para la aplicación client.exe y llámelo client.exe.manifest. Pegue lo siguiente en el archivo:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" 
   manifestVersion="1.0">
<assemblyIdentity
            type = "win32"
            name = "client"
            version = "1.0.0.0" />
<dependency>
            <dependentAssembly>
                        <assemblyIdentity
                                    type="win32"
                                    name="SideBySide"
                                    version="1.0.0.0" />
            </dependentAssembly>
</dependency>
</assembly>

Paso 9

En la carpeta del proyecto SideBySide, cree un archivo de manifiesto de ensamblado privado (un archivo de texto) y llámelo SideBySide.manifest. Pegue lo siguiente en el archivo:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" 
  manifestVersion="1.0">
<assemblyIdentity
            type="win32"
            name=" SideBySide"
            version="1.0.0.0" />
<clrClass
            clsid="{[CLSID_SideBySideClass]}"
            progid="SideBySide.SideBySide"
            threadingModel="Both"
            name="SideBySide.SideBySideClass" >
</clrClass>
</assembly>

La siguiente tarea consiste en insertar el archivo de manifiesto de ensamblado anterior en el ensamblado SideBySide como un recurso Win32. En el momento de escribir esto es obligatorio para Windows XP, pero no para Windows Server 2003. En Windows Server 2003, puede salir con simplemente implementar el archivo de manifiesto de ensamblado junto con el ensamblado. Sin embargo, le ruego que no dependa de este comportamiento, ya que puede cambiar bien en un próximo Service Pack de Windows Server 2003. Para asegurarse de que sigue admitiendo ambas plataformas en el futuro, siga los pasos siguientes e inserte el archivo de manifiesto de ensamblado en el ensamblado de .NET como un recurso Win32. Esto solo es necesario para la activación sin registro de . Componentes de basados en NET y no es un requisito para la activación sin registro de componentes nativos de COM.

Paso 10

En la carpeta SideBySide proyecto, cree un archivo de script de definición de recursos (un archivo de texto) y llámelo SideBySide.rc. Pegue lo siguiente en el archivo:

#include <windows.h>
#define MANIFEST_RESOURCE_ID 1
MANIFEST_RESOURCE_ID RT_MANIFEST SideBySide.manifest

El archivo windows.h y sus dependencias están disponibles al instalar platform SDK (sección Core SDK) o Visual C++. La parte de windows.h que se requiere aquí es la definición:

#define RT_MANIFEST 24

Por lo tanto, el contenido de SideBySide.rc resolver para:

1 24 SideBySide.manifest

Sin embargo, es más claro y más general usar las definiciones de macro como se indica.

Paso 11

En el SideBySide carpeta del proyecto, cree un archivo de comandos de compilación (un archivo de texto) y llámelo build.cmd. Pegue lo siguiente en el archivo:

Para compilar C#:

rc SideBySide.rc
csc /t:library /out:..\deployed\SideBySide.dll 
/win32res:SideBySide.res Class1.cs

Para compilar Visual Basic .NET:

rc SideBySide.rc
vbc /t:library /out:..\deployed\SideBySide.dll 
/win32resource:SideBySide.res /rootnamespace:SideBySide Class1.vb

Lo que hacen estos comandos es primero invocar la herramienta compilador de recursos de Microsoft Windows desde platform SDK (rc.exe) para compilar el script de definición de recursos del paso 10 en un archivo de recursos compilado denominado SideBySide.res. A continuación, invoca el compilador de .NET de C# o Visual Basic para compilar el archivo de código fuente en un ensamblado e insertar el archivo de recursos compilado en él como un recurso Win32. El ensamblado compilado se escribe en la carpeta \deployed, pero no se registrado para la interoperabilidad COM.

Paso 12

En un símbolo del sistema de Visual Studio 2003, vaya a la carpeta SideBySide proyecto y ejecute el comando: build.

Paso 13

Para comprobarlo, cortesía de los archivos de manifiesto, el cliente puede activar la clase SideBySideClass a través de la interoperabilidad COM, ejecutar \deployed\client.exe y anotar el resultado esperado "1.0.0-C#" o "1.0.0-VB.NET".

Solución de problemas

Como hemos visto, la activación sin registro de componentes basados en .NET Framework no requiere ningún código especial en el servidor o en el cliente. Todo lo necesario es un par coincidente de archivos de manifiesto, uno de los cuales está incrustado en el ensamblado de .NET como un recurso win32 de tipo RT_MANIFEST.

Sugiero que se acerque a su propio desarrollo libre de registro como lo hace este tutorial. En concreto: primero llegue a un estado conocido viendo que el cliente trabaja con un servidor registrado; a continuación, anule el registro del servidor y confirme que el mensaje de error es lo que esperaba; y, por último, solucione la situación mediante la creación e implementación de archivos de manifiesto. De este modo, los esfuerzos de solución de problemas relacionados con la activación sin registro se limitarán a la estructura de los archivos de manifiesto y a la inserción correcta del manifiesto del ensamblado.

Al solucionar problemas de COM sin registro, el Visor de eventos en Windows Server 2003 es su amigo. Cuando Windows XP o Windows Server 2003 detectan un error de configuración, normalmente mostrará un cuadro de mensaje de error titulado para la aplicación que ha iniciado y que contiene el mensaje "Esta aplicación no se ha podido iniciar porque la configuración de la aplicación es incorrecta. La reinstalación de la aplicación puede solucionar este problema". Le recomiendo que, cada vez que vea este mensaje, reproduzca el problema en Windows Server 2003, consulte el registro de eventos del sistema y busque eventos del origen de SideBySide. La razón por la que no sugiero que examine el registro de eventos de XP en estos casos es que contendrá invariablemente un mensaje como "Error de contexto de activación para [ruta]\[nombre de archivo de la aplicación]. Manifiesto. Mensaje de error de referencia: la operación se completó correctamente", lo que no ayuda a identificar el problema.

Antes de pasar a la estructura de los archivos de manifiesto, vamos a hablar de los recursos de Win32. Como mencioné anteriormente, windows.h define el símbolo RT_MANIFEST como el valor 24, que es el valor que el sistema operativo reconocerá como un archivo de manifiesto incrustado. Si olvida incluir windows.h en el script de definición de recursos (archivo.rc), la compilación seguirá funcionando correctamente y el archivo de manifiesto seguirá insertado como un recurso, pero no del tipo correcto. Para comprobar que ha incrustado correctamente su manifiesto, abra el SideBySide.dll en Visual Studio ( archivo| Abrir | Archivo...). Verá una vista de árbol en la que se muestran los recursos dentro del módulo. En el nodo raíz debe ser un nodo denominado RT_MANIFEST debajo, que debe ser otro nodo que muestre el número de recurso del recurso de manifiesto (1 en el tutorial). Haga doble clic en este último nodo para ver los datos en una vista binaria y darle una comprobación rápida de integridad de que se parezca al archivo de manifiesto XML. Aunque es binario, los caracteres del intervalo ASCII serán obvios. Si faltan datos binarios o parece incorrecto, compruebe que el script de definición de recursos (archivo.rc) hace referencia al archivo de manifiesto. Si el texto del nodo RT_MANIFEST está entre comillas, es probable que haya olvidado incluir windows.h en el script de definición de recursos (archivo.rc).

Cada uno de los errores mencionados se notificará en el registro de eventos del sistema de Windows Server 2003 con el mensaje: "No se encontró el ensamblado dependiente [nombre] y el último error fue el ensamblado al que se hace referencia no está instalado en el sistema".

Los esquemas de los distintos archivos de manifiesto se documentan en el SDK de plataforma bajo el encabezado Referencia de archivos de manifiestoy la herramienta de validación de esquemas Manifestchk.vbs está disponible, por lo que aquí solo llamaré algunos puntos relevantes para el tutorial. En primer lugar, vamos a examinar el archivo de manifiesto del ensamblado. Por ejemplo, vuelva al paso 9.

Recordará que, en el sentido COM sin registro , un de ensamblado es una idea abstracta con la que asocia uno o varios archivos físicos mediante el contenido del manifiesto de ensamblado archivo.

El elemento assemblyIdentity define la identidad del ensamblado . Para. Los componentes basados en NET nombre atributo deben coincidir con el nombre del ensamblado .NET y, por tanto, su nombre de archivo; de lo contrario, verá el siguiente mensaje en el registro de eventos del sistema de Windows Server 2003: "Ensamblado dependiente [valor de nombre atributo] no se encontró y El último error fue El ensamblado al que se hace referencia no está instalado en el sistema". Sin embargo, la versión de atributo no necesita coincidir con la AssemblyVersion del ensamblado de .NET, ni su AssemblyFileVersion, aunque es una buena idea aplicar algún tipo de coherencia.

El elemento clrClass solo tiene dos atributos obligatorios: nombre y clsid. El nombre de atributo debe coincidir con el espacio de nombres y el nombre de clase combinados de la clase CLR que se está activando. Si no lo hace, CoCreateInstance devolverá un HRESULT con el valor COR_E_TYPELOAD (0x80131522). Esto se debe a que se produce una excepción System.TypeLoadException cuando el cargador de tipos no encuentra el tipo CLR solicitado en el ensamblado de .NET. Una cosa que debe tener en cuenta si el ensamblado de .NET está escrito en Visual Basic .NET es que está proporcionando el modificador /rootnamespace en la línea de comandos al compilador de .NET de Visual Basic (vbc.exe). El atributo clsiddebe coincidir con el CLSID asignado a la clase CLR que se activa a través de su GuidAttribute. Si no lo hace, CoCreateInstance devolverá un HRESULT con el valor REGDB_E_CLASSNOTREG (0x80040154), el texto del mensaje para el que es "Clase no registrada".

Ahora vamos a poner nuestra atención en el archivo de manifiesto de aplicación. Por ejemplo, vuelva al paso 8. El manifiesto de aplicación debe tener el nombre en el formato [nombre de archivo de aplicación].manifest. Por lo tanto, en el tutorial se le llamó client.exe .manifest para que quede claro que debe leerse cada vez que client.exe se carga en un proceso. Si esto no se realiza correctamente, CoCreateInstance devolverá un HRESULT con el valor REGDB_E_CLASSNOTREG (0x80040154), el texto del mensaje para el que es "Clase no registrada".

El elemento más importante del manifiesto de aplicación es el elemento dependentAssembly/assemblyIdentity. Este elemento es una referencia al equivalente del manifiesto del ensamblado y los dos tienen que coincidir exactamente. Una buena manera de asegurarse de que lo hacen es copiar el elemento del manifiesto del ensamblado y pegarlo aquí. Si hay alguna diferencia, verá el siguiente mensaje en el registro de eventos del sistema de Windows Server 2003: "La identidad del componente encontrada en el manifiesto no coincide con la identidad del componente solicitado".

Conclusión

COM sin registro es una tecnología que libera los componentes COM de una dependencia en el Registro de Windows y, por tanto, libera las aplicaciones que las usan de requerir servidores dedicados. Permite que las aplicaciones con dependencias en diferentes versiones del mismo componente COM compartan una infraestructura y carguen esas distintas versiones de componentes COM en paralelo en un eco del mecanismo de implementación y control de versiones de .NET.

Este artículo le guiará a través de una demostración de la activación sin registro de los componentes basados en .NET Framework por las aplicaciones cliente nativas escritas en Visual C++ y Visual Basic 6.0. Explicó algunos de cómo funciona el mecanismo y ha subrayado algunos posibles errores de configuración y cómo solucionarlos.

Lectura adicional

 

Acerca del autor

Steve White es un consultor de desarrollo de aplicaciones que trabaja en el equipo premier de soporte técnico para desarrolladores en Microsoft UK. Admite el desarrollo de clientes con Visual C#, Windows Forms y ASP.NET. Su blog tiene más información sobre sus intereses en la música, las visualizaciones y la programación.

Leslie Muller es un tecnólogo con el equipo de Investigación & Desarrollo en Credit Suisse First Boston. Leslie tiene 12 años de experiencia como desarrolladora y arquitecto técnico, trabajando en entornos como servicios financieros, startups tecnológicas, automatización industrial y defensa. Cuando no está programando o investigando disfruta de esquí, hockey sobre hielo y cuando sea posible haciendo cosas ligeramente locas con vehículos motorizados en entornos extremos como Islandia o las Rocas.