ComInterop in C# e VB.NET

Creazione del progetto .NET di base

Dopo essersi letti un po’ di teoria, passiamo alla realizzazione di una vera classe C# da utilizzare all’interno di un programma VB6.

Come specificato nel post precedente, se si utilizza VB.NET c’e’ gia’ un template di progetto pronto per l’interoperabilita’. Utilizzando invece C# (o VB.NET con Visual Studio 2008) occorre farsi le cose a manina. Di seguito uno snippet di codice per creare la classe di base.

using System;
using Microsoft.VisualBasic;

namespace TestRegistazioneCom
{

[ComClass(TestComInterop.ClassId, TestComInterop.InterfaceId, TestComInterop.EventsId)]
public class TestComInterop
{
	public const string ClassId = "233D23FD-68C0-4da6-9749-8E137127692F";
	public const string InterfaceId = "6ACCBB64-3A0A-46ee-B8F8-9537CEBF2136";
	public const string EventsId = "B6A186AB-6212-4ab1-B998-7F471C5AE94B";

	public TestComInterop()
	{
	}

	public string GetName()
	{
		return "RainbowBreeze";
	}
}
}

I GUID (quelle lunghe stringe di numeri) vanno cambiati e messi nuovi, magari utilizzando il GUID Generator di Visual Studio (Tools -> Create Guid)

Configurazione del progetto .NET per l’interoperabilita’

Andare nelle proprieta’ del progetto, tab Application, bottone Assembly Information

Title: il titolo dell’assembly, viene messo in HKEY_CLASSES_ROOT ed e’ quello che apparira’ come nome della libreria creata
Description: la descrizione che apparira’ dentro VB6 quando si andranno ad aggiungere nuove reference
Version: la versione con cui la libreria .NET viene registrata
GUID: il GUID utilizzato per registrare l’oggetto all’interno del registry (HK_CR\TypeLib\). Viene generato automaticamente e deve essere univoco per non sovrapporsi ad altri GUID di altre librerie registrate nel sistema  Make Assembly COM-visible: va flaggata questa opzione

Registrazione della nuova DLL nel sistema

Se nelle proprieta’ del progetto .NET, tab Build, viene impostata la voce “Register for Com Interop“, quando il progetto viene compilato, Visual Studio pensa anche a generare il relativo tlb (un proxy per VB6 necessario all’interoperabilita’) e registrarlo all’interno del sistema. Se questo puo’ sembrare un comodo automatismo, in realta’  va bene solo per la macchina di sviluppo, dato che il tlb viene generato all’interno della cartella bin\debug o bin\release del progetto e registrato in quel percorso.

Nella macchina di deploy, occorre registrare manualmente il tlb generato, per mezzo del comando regasm.exe: copiare la dll .NET nella cartella dove andra’ a finire in maniera definitiva, e poi eseguire il comando regasm per generare il tlb e registrarlo nel sistema. Ponendo che la classe da registrare si chiami TestRegistrazioneCom.dll, la sintassi del regasm sara’:

regasm TestRegistrazioneCom.dll /tlb:TestRegistrazioneCom.tlb

Come ultimo passo, occorre registrare la DLL .NET della GAC (Global Assembly Cache), in modo che il tlb sappia chi chiamare quando i suoi metodi vengono invocati. In alternativa, si puo’ anche lasciare la dll .NET nella stessa cartella dell’eseguibile VB6, senza bisogno di registrazioni nella GAC.

Utilizzi avanzati

Se si vuole costruire una nuova classe .NET che deve pero’ mantenere la compatibilita’ con un precedente oggetto COM, andandolo a sostituire in maniera trasparente alle applicazioni che lo utilizzano, si puo’ agire sul GUID e sul Title del nuovo progetto .NET, impostandoli come quelli della classe da sostituire. Occorrera’ poi accertarsi che anche i metodi esposti siano gli stessi. Con questa attenzione, basta deregistrare la vecchia libreria VB6 e registrare la nuova libreria .NET e tutto dovrebbe andare.

Altre guide che parlano della COM Interop, invece di registrare direttamente la classe .NET concreta, registrano un’interfaccia, che poi la classe .NET va ad implementare.
Mi sembra una soluzione piu’ pulita, ma alla fine ogni soluzione ha il suo contesto corretto.

References:
Interop Forms Toolkit 2.0 Tutorial – assolutamente da leggere
VB6 Interop – Bringing VB6 into the .NET fold
Using .NET Controls in VB6

2 Comments

Leave a Reply