Domanda

Sto tentando di esporre la nostra libreria tramite COM, ma sembra che stia combattendo gli strumenti più del vero problema. Indipendentemente da come scrivo la mia classe esposta COM, ricevo l'avvertimento: & Quot; XXX.dll non contiene alcun tipo che può essere registrato per l'interoperabilità COM & Quot; (progetto contrassegnato come Registro per l'interoperabilità COM nelle proprietà del progetto). Persino la semplice classe di seguito (poiché l'unica classe in un assembly firmata e contrassegnata con ComVisible (false)) persiste ancora:

  [Guid("77699130-7D58-4d29-BE18-385871B000D1")]
  [ComVisible(true)]
  public interface IExample
  {
    string GetText();
    void SetText(string text);
  }

  [Guid("F91E5EE1-D220-43b5-90D1-A48E81C478B7")]
  [ComVisible(true)]
  public class Example : IExample
  {
    private string m_text = "default text";

    public string GetText()
    {
      return m_text;
    }

    public void SetText(string text)
    {
      m_text = text;
    }
  }

Ho provato ad eseguire il regasm dalla riga di comando sull'output che indica volentieri " Tipi registrati correttamente " ;. Tuttavia, in esecuzione con l'opzione / verbose non vengono visualizzate informazioni aggiuntive (mi sembra di ricordare che elenca il nome o forse solo il numero di tipi registrati). Ho anche provato a eseguire regasm con l'opzione / regfile per generare un regfile che genera questo:

[HKEY_CLASSES_ROOT\ComExample.Example]
@="ComExample.Example"

[HKEY_CLASSES_ROOT\ComExample.Example\CLSID]
@="{F91E5EE1-D220-43B5-90D1-A48E81C478B7}"

[HKEY_CLASSES_ROOT\CLSID\{F91E5EE1-D220-43B5-90D1-A48E81C478B7}]
@="ComExample.Example"

[HKEY_CLASSES_ROOT\CLSID\{F91E5EE1-D220-43B5-90D1-A48E81C478B7}\InprocServer32]
@="mscoree.dll"
"ThreadingModel"="Both"
"Class"="ComExample.Example"
"Assembly"="COMInteropTesting, Version=1.0.0.0, Culture=neutral, PublicKeyToken=8568e57f6b170d6c"
"RuntimeVersion"="v2.0.50727"

[HKEY_CLASSES_ROOT\CLSID\{F91E5EE1-D220-43B5-90D1-A48E81C478B7}\InprocServer32\1.0.0.0]
"Class"="ComExample.Example"
"Assembly"="COMInteropTesting, Version=1.0.0.0, Culture=neutral, PublicKeyToken=8568e57f6b170d6c"
"RuntimeVersion"="v2.0.50727"

[HKEY_CLASSES_ROOT\CLSID\{F91E5EE1-D220-43B5-90D1-A48E81C478B7}\ProgId]
@="ComExample.Example"

[HKEY_CLASSES_ROOT\CLSID\{F91E5EE1-D220-43B5-90D1-A48E81C478B7}\Implemented Categories\{62C8FE65-4EBB-45E7-B440-6E39B2CDBF29}]

Non sono un mago COM di nessuna misura ma la registrazione mi sembra valida. Tuttavia, nulla sembra apparire nel registro durante l'esecuzione del regasm sull'assembly.

Quindi la mia domanda è se mi manca qualcosa nel mio semplice esempio per far funzionare la registrazione, sto vedendo false indicazioni e la registrazione è effettivamente corretta e come posso determinare meglio se la registrazione COM funziona davvero

EDIT: Usando le modifiche suggerite da Kev non ho potuto evitare gli avvertimenti di VS2008, ma in realtà ho potuto ottenere qualcosa registrato nel registro usando direttamente regasm (niente nel registro solo dall'integrazione VS2008).

Ho quindi provato a rimuovere la classe semplice, quindi avevo un assembly vuoto. L'esecuzione del regasm su questo non ha riportato alcun tipo di avvertimento, solo & Quot; Tipi registrati correttamente & Quot ;. Vedo avvisi come & Quot; RegAsm: avviso RA0000: nessun tipo registrato & Quot; quando eseguo RegAsm su alcuni dei miei altri assembly che potrebbero essere erroneamente esposti a COM. Cosa sta succedendo qui, posso fidarmi di qualcosa tranne il registro e che dire degli avvisi on / off del regasm?

È stato utile?

Soluzione

Ho creato un progetto di libreria di classi basato sul tuo codice come segue:

Nella pagina delle proprietà del progetto, selezionare la scheda Firma. Seleziona la casella di controllo "Firma l'assembly" e seleziona <New...> dalla casella a discesa "Scegli un file chiave con nome sicuro:".

Ho quindi aggiunto la seguente classe (Example.cs):

[Guid("77699130-7D58-4d29-BE18-385871B000D1")]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
[ComVisible(true)]
public interface IExample
{
    [DispId(1)]
    string GetText();

    [DispId(2)]
    void SetText(string text);
}

[Guid("F91E5EE1-D220-43b5-90D1-A48E81C478B7")]
[ClassInterface(ClassInterfaceType.None)]
[ComVisible(true)]
public class Example : IExample
{
    private string m_text = "default text";

    [ComVisible(true)]
    public string GetText()
    {
      return m_text;
    }

    [ComVisible(true)]
    public void SetText(string text)
    {
      m_text = text;
    }
}

Ho quindi creato il progetto, quindi sono passato a una riga di comando in cui la DLL è stata emessa dalla build.

Per registrarsi:

  

regasm.exe COMInteropTesting.dll /register /codebase /tlb

Se il componente deve essere accessibile a più applicazioni:

  

gacutil.exe -i COMInteropTesting.dll

Tutto ha funzionato bene su Windows 2003 a 32 bit, Windows 2008 a 32 bit e Windows 7 a 64 bit.

Un problema però è che se stai testando il componente con diciamo CScript su un sistema a 64 bit, devi eseguire l'interprete CScript corretto. Se hai registrato l'assembly utilizzando 32 bit RegAsm.exe (a C:\Windows\Microsoft.NET\Framework\v2.0.50727), devi eseguire l'interprete CScript a 32 bit su c:\Windows\SysWOW64.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top