giovedì 9 settembre 2010

C# COM Visible

Risolviamo questo problema una volta per tutte.

C'e' tanta letteratura nel web sull'argomento, ma è davvero complesso ottenere una soluzione veritiera. C'e' chi afferma che serva solo un flag nell'assembly info, c'e' chi afferma che è necessario
lo strong Name, c'e' chi afferma che servono danze e balli propriziatori o congiunzioni astrali...

C'e' chi come me prova e ottiene la solzuione senza dover ricorrere a strani oracoli.

-Step by step C#Com Visible
1) create una nuova soluzione di tipo Class Library
2) create una classe
3) aggiungete il namespace System.Runtime.Interop
4) aggiungete alla classe i vostri Metodi / Proprietà
5) aggiungete ai metodi che devono essere COM visible gli Attributi
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
6) aggiungete (se non lo fate per abitudine i commenti ///summary)
7) create un INTERFACE che mappa tutti i Metodi e tutte le proprietà COM visible della classe
8) aggiungete alla classe l'interfaccia.

-Codice d'esempio
(ho rimosso il maggiore e il minore nei summary)

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;

namespace ComVisibleTest
{

public interface iComTest
{
string HelloWord();
int GetInt();
}

[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
public class ComTest:iComTest
{
/// summary
/// Non fa nulla ma lo fa bene
/// /summary
/// returns/returns
[ComVisible(true)]
public string HelloWord()
{
return "ciao mondo";
}

/// summary
/// Restituisce il mio numero preferito.
/// /summary
/// returns/returns
[ComVisible(true)]
public int GetInt()
{
return 7;
}
}
}

-Come e cosa fare negli Attributi dell'Assembly
Nelle proprietà del progetto è necessario esplicitare che si tratta di un ComVisible.
Quindi dalle proprietà del progetto/assembly information settare:
MAKE ASSEMBLY COM VISIBLE = true.

Nelle proprietà del progetto sotto build può essere necessario indicare di ri registrare
ad ogni build l'assembly
Quindi dalle proprietà di build settare:
REGISTER FOR COM INTEROP = true.

-Volte davvero fare un salto di qualità ??
Nelle azioni di build in POST BUILD
Regasm [nome della libreria].dll /tlb:[nome della libreria.]tlb
es
Regasm ComVisibleTest.dll /tlb:ComVisibleTest.tlb


-Qualche info in più...
a) L'interfaccia, serve anzi è necessaria, perchè rappresenta l'entryPoint, o header della nostra dll. Come questa venga tratta, o come questa venga resa a livello di TLB, giuro non lo so. Ma senza l'interfaccia VB6 ( mio caso di test per questo prototipo ) vede la classe ma non i metodi, aggiungendo l'interfaccia VEDO TUTTO.

b) in VB.Net tutto questo non serve, anzi basta solo indicare che la nostra libreria è comvisible.

c) E' possibile che in caso la soluzione sia composta da più libreria, si devono realizzare tante
interfaccie per quante classi dovranno essere rese come COMvisible.


-Note Tecniche sull'ambiente:
Visual Studio 2008 tipo di build "Release X86"
Visual basic 6 sp 6
Windows 7 64 bit