Come ottenere COM senza registrazione funzionante in interoperabilità gestita / non gestita

StackOverflow https://stackoverflow.com/questions/5392152

  •  28-10-2019
  •  | 
  •  

Domanda

Ho un oggetto COM in-process C ++ / ATL non gestito (in Unmanaged.dll) che sto cercando di utilizzare da una DLL C # gestita (Managed.dll). Tuttavia, desidero utilizzare COM senza registrazione. Penso a questi passaggi:

  • Registra l'oggetto COM sulla macchina di sviluppo. Il server in-process deve avere una libreria dei tipi registrata correttamente.
  • Aggiungi un riferimento all'oggetto COM all'interno del progetto C #, quindi imposta le proprietà di riferimento su Isolated= True.

Questo produce Unmanaged.dll, Managed.dll e Native.Managed.manifest. Aprendo il manifest, è abbastanza chiaro come il sistema lo utilizzi per caricare l'oggetto COM in modo privo di registrazione.

Ecco il problema. Ho un EXE gestito (Managed.exe) che carica dinamicamente Managed.dll per accedere ai tipi pubblici. Quello che intendo per "dinamicamente" è che utilizza Assembly.LoadFrom ("Managed.dll"). Quando il codice all'interno di Managed.dll tenta di creare l'oggetto COM, ottiene un'eccezione "classe non registrata". Sembra che il contesto di attivazione non venga configurato correttamente quando viene caricato Managed.dll.

Esiste un modo per far funzionare COM senza registrazione in questo scenario?

È stato utile?

Soluzione

Due giorni senza risposta, quindi ecco cosa mi è venuto in mente in quel periodo ...

Sembra che il contesto di attivazione sia impostato dal sistema operativo all'avvio del processo in base al manifest associato all'EXE principale. Ciò significa che tutti gli elementi relativi a COM senza registrazione devono trovarsi in Main.exe.manifest al momento dell'avvio del processo. Ciò interrompe l'isolamento tra EXE e DLL. Se una DLL è responsabile della creazione di oggetti COM, non ti aspetteresti che il manifest EXE contenga le informazioni COM prive di registrazione. Potresti aspettarti che il manifest associato alla DLL venisse unito al contesto di attivazione del processo nel momento in cui la DLL viene caricata, ma non è così.

Per aggirare questo problema, la DLL deve configurare un nuovo contesto di attivazione prima di creare l'oggetto COM. A peggiorare le cose, attualmente (a partire da .NET 4.0) non esiste un modo gestito per farlo. Quindi, la DLL dovrà PInvoke le seguenti funzioni Win32:

Ho racchiuso queste chiamate con una classe gestita che chiama CreateActCtx e ActivationActCtx nel costruttore e DeativateActCtx e ReleaseActCtx in IDisposable :: Dispose.

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