Consumiendo un Web Service desde VB6

Fecha: 14/May/2005 (09/05/2005)
Autor: Luis Véliz (lveliz@mundoedwards.com)

 


Introducción

En este artículo se abordan algunos conceptos de interoperabilidad y se muestra a través de un ejemplo práctico como poner a trabajar estos conceptos.  Se revisarán materias como GAC (Global assembly Cache), ensamblado, registro de componentes NET para ser consumidos desde COM y se mostrará como consumir un Web Service desde VB6.  Este ejemplo reune todos los pasos para registrar un componente convencional NET (Assembly) para ser consumido desde COM y las particularidades para hacer los propio con un Web Service.

Consumiendo un componente NET desde COM

Conceptos previos

Antes de mencionar los pasos involucrados para compilar un componente NET y registrarlo para usarlo desde COM, revisaremos algunos conceptos necesarios para entender el proceso.

a.-  Assembly (Ensamblado)

Un ensamblado es un conjunto de módulos administrados relacionados lógicamente.  Los ensamblados no se ejecutan así mismos sino que son ejecutados por una plataforma que forma parte del Framework de .NET, el CLR (Common Language Runtime).  De ahí el concepto de código administrado.  La ejecución de los ensamblados de NET es realizada por el CLR y puede administrarse por ejemplo para controlar conceptos como el manejo de versiones y algunas otras características que determinarán el comportamiento de la aplicación.

b.-  Global Assembly Cache (GAC)

El GAC corresponde a un área común donde se almacenan los ensamblados de .NET.  Un ensamblado de .NET puede ser privado para la aplicación (ubicado en directorio bin de la aplicación) o global para ser consumido por más de una aplicación.  Cuando este es el caso (ensamblado global), lo que se debe hacer es poner el ensamblado en el GAC.  Con esto se evita tener que especificar una ubicación fija para el ensamblado a través de la directiva 'codebase'.  Para nuestro ejemplo pondremos el ensamblado en el GAC para garantizar que podrá ser ubicado por nuestra aplicación VB6.

c.- Firma de ensamblados (Strong Name)

Antes de poner un ensamblado en el GAC, este debe ser firmado para garantizar que tenga un identificador único dentro del GAC.  Este identificador se conoce como Strong Name, que es obtenido a partir del nombre del archivo, la versión y una llave publica/privada. Toda esta información se obtiene desde el archivo de ensamblado (Assembly.vb en el caso de una aplicación VB.NET).  La llave publica privada se proporciona a través de un arhivo .snk que puede ser obtenido utilizando la herramienta SN.EXE del SDK de .NET.  Esta herramienta genera un archivo (.snk) que debe ser referenciado utilizando el atributo AssemblyKeyFile en el archivo de ensamblado de la aplicación.  A continuación se muestra un archivo de ensamblado donde se ha agregado una referencia a la llave generada con la herramienta SN.exe (ver el archivo sn.bat en la carpeta Deploy del ejemplo)

Imports System
Imports System.Reflection
Imports System.Runtime.InteropServices
' La información general de un ensamblado se controla mediante el siguiente
' conjunto de atributos. Cambie estos atributos para modificar la información
' asociada con un ensamblado.
<Assembly: Assembly Description ("Descripcion Assembly")>
<Assembly : Assembly Company("Compañia")>
<Assembly: Assembly Product("")>
<Assembly: Assembly Copyright("")>
<Assembly: Assembly Trademark("")>
<Assembly : CLSCompliantTrue()>
<Assembly : AssemblyKeyFile("C:\Inetpub\wwwroot\WebServiceFromVB6\Deploy\llave.snk")>
'El siguiente GUID sirve como identificador de la biblioteca de tipos si este proyecto se expone a COM
<Assembly : Guid(? FDC1F366-870F-4411-A795-E7F4B7574593?)>
' La información de versión de un ensamblado consta de los siguientes cuatro valores:
' Versión principal
' Versión secundaria
' Versión de compilación
' Revisión
' Puede especificar todos los valores o usar los valores predeterminados (número de versión de compilación y de revisión)
' usando el símbolo '*' como se muestra a continuación:
<Assembly : AssemblyVersion(? 2.0.*?)>
 

d.-  Wrapper: COM Collable Wrapper (CCW)

Para poder consumir un componente NET desde COM, es necesario 'envolver' el ensamblado para presentarlo a COM como cualquier otro componente COM.  Esto es lo que se conoce como Wrapper en la gerga de interoperabilidad.  Específicamente para el caso de los componentes NET que serán consumidos desde COM el 'wrapper' se nombra como CCW (COM Collable Wrapper).

El CCW envuelve el objeto NET y proporciona la interfaz para que COM pueda comunicarse de manera transparente con el objeto NET.  El objeto NET es presentado a COM como cualquier otro componente COM.

Entonces, uno de los pasos que se debe completar para poder consumir el Web Service del ejemplo, desde COM, es generar el CCW (archivo tlb generado con regasm.exe).

Preparando el Web Service para ser consumido desde COM

Los pasos que se deben llevar a cabo para consumir el Web Service desde nuestra aplicación VB6 son los siguientes:
(todos los argumentos de los comandos, se basan en el ejemplo adjunto.  El servidor que aloja el Web Service es localhost.  El Web Service se ubica en la carpeta WebServiceFromVB6 en la raíz del directorio predeterminado del sitio WEB.  El Web Service utiliza la base de datos Northwind y el Application Block de acceso a datos)

1.-  Compilar el Web Service: Este paso genera el ensamblado del Web Service.  Esto se realiza desde el IDE de Visual Studio .NET

2.-  Generar la clase proxy del Web Service: Con esto se genera una nueva clase, que contiene la información necesaria para saber donde se ubica y como realizar las llamadas a los métodos expuestos en el Web Service.

Utilizar la herramienta WSDL.EXE.  Ejemplo: 

wsdl.exe /out: ProxyWebServiceFromVB6.vb /namespace: lveliz.mynamespace /l:vb http://localhost/WebServiceFromVB6/service01.asmx?wsdl

3.-  Compilar la clase proxy generada:  Esto se realiza utilizando la herramienta VBC.EXE. El resultado de esta operación será un nuevo ensamblado.  En este paso se debe firmar el ensamblado con un nombre fuerte (Strong Name).  Este será el ensamblado que pondremos en el GAC y que dará el acceso desde la aplicación VB6 al Web Service.  Ejemplo:

vbc.exe /out:ProxyWebServiceFromVB6.dll /t:library /keyfile:llavepublicaprivada.snk /r:System.dll,System.Web.Services.dll,System.Xml.dll /recurse:AssemblyInfo.vb WebServiceFromVB6.vb

4.-  Generar la biblioteca de clases COM desde el ensamblado generado en el paso anterior y registrarlo para ser usado desde la aplicación VB6.  Ejemplo:

regasm.exe /tlb:ProxtWebServiceFromVB6.tlb ProxyWebServiceFromVB6.dll

5.-  Poner el ensamblado en el GAC

gacutil.exe /I ProxyWebServiceFromVB6.dll

6.-  Referenciar el objeto registrado desde la aplicación VB6 y utilizarlo como cualquier otro componente COM.

Nota: En los archivos adjuntos, se entrega un archivo .bat (registra.bat en la carpeta Deploy) que realiza las tareas enumeradas anteriormente (pasos 2,3, 4, 5)

Los siguientes archivos son generados luego de ejecutar registra.bat:
ProxyWebServiceFromVB6.vb (clase proxy generada por wsdl.exe)
ProxyWebServiceFromVB6.dll (assembly generado por vbc.exe)
ProxyWebServiceFromVB6.tlb (biblioteca de tipos generada por regasm.exe)

Conclusiones

El FrameWork de .NET proporciona todos los mecanismos necesarios para interoperar con COM.  En el ejemplo de este artículo se mostraron los pasos para lograr la interoperabilidad con un Web Service, sin embargo esto aplica para cualquier componente NET.  Los pasos particulares para el Web Service son los que tienen relación con la generación de la clase y el ensamblado Proxy, la generación de las librería de tipos y el registro para COM es común a todos los compoentes NET.

También es posible invocar funciones de la API de Win32 (PlataformInvoke) y consumir componentes COM desde NET, es decir la interoperación es soportada en ambos sentidos: NET desde COM (como el ejemplo) y COM desde NET. 


Fichero con el código de ejemplo: lveliz_ConsumiendoUnWebServiceDesdeVB6.zip - 28.1 KB


ir al índice