2011-12-16 21 views
7

Sto scrivendo un piccolo componente DLL che deve accedere a due componenti di terze parti per combinare i dati, uno dei quali è solo a 32 bit e l'altro solo a 64 bit. Entrambi sono registrati con TypeLib e sono compatibili con l'automazione, quindi il marshalling non dovrebbe essere un problema.COM surrogato per componente di terze parti

Se ho letto correttamente la documentazione, non c'è modo di forzare il caricamento in un surrogato a meno che il componente abbia anche un AppID e la chiave DllSurrogate; Poiché entrambi sono componenti di terze parti, sono piuttosto riluttante a modificare la loro registrazione.

C'è un modo per attivare un oggetto in un componente senza un AppID in un processo surrogato da un componente DLL che idealmente non ha altre dipendenze, o qualcuno può spiegarmi perché questa sarebbe una cattiva idea?

+1

http://msdn.microsoft.it/it/us/library/windows/desktop/ms682432% 28v = vs.85% 29.aspx –

+1

Un surrogato personalizzato non richiede che il componente server abbia un AppID, quindi COM sa quale surrogato istanziare la classe in ? Se aggiungo questo, ciò influenzerebbe tutti i client, non solo il mio componente, che preferirei evitare (inoltre, il surrogato standard dovrebbe funzionare correttamente). –

+0

[Raymond Chen] (http://blogs.msdn.com/b/oldnewthing/archive/2009/02/12/9413816.aspx) suggerisce che l'Explorer può in qualche modo oggetti 'CoCreateInstance' che non sono registrati con * DllSurrogate * chiave in modo che vengano creati in un surrogato - sarei interessato a come. –

risposta

6

Sì, è possibile caricare (ad esempio) solo DLL a 32 bit in un surrogato e accedervi da un processo a 64 bit, nel modo seguente. Ciò funzionerà a condizione che sia disponibile un marshaller, che in genere sarà disponibile per un componente con un typelib perché in genere utilizzano il marshaller standard. Non funzionerà se l'oggetto richiede un prox/stub personalizzato perché le versioni a 64 bit non esisteranno, o non avresti questo problema in primo luogo.

Per prima cosa è necessario un AppID. Se la DLL ha già un AppID, dovresti usarlo. Puoi scoprirlo selezionando la chiave CLSID per la CoClass a cui sei interessato.

L'esempio utilizzato qui è le classi Capicom.HashedData e Capicom.EncryptedData. Capicom è solo a 32 bit.

Per eseguire questa operazione, è necessario utilizzare la versione a 32 bit di Regedit, in quanto è un componente a 32 bit. Se si dispone di un componente a 64 bit a cui si desidera accedere da 32 bit, utilizzare l'altro. (Ciò è dovuto alla virtualizzazione del registro per il livello di compatibilità a 32 bit, utilizzando la versione corrispondente di regedit che si occupa di questo problema per te, assicurandoti di modificare la versione virtualizzata corretta del registro).

Windows Registry Editor Version 5.00 


;;; Capicom AppID - just using the Capicom.EncryptedData CLSID 
;;; Use default surrogate = empty string 
[HKEY_CLASSES_ROOT\AppID\{A440BD76-CFE1-4D46-AB1F-15F238437A3D}] 
"DllSurrogate"="" 

;;; Capicom.EncryptedData 
[HKEY_CLASSES_ROOT\CLSID\{A440BD76-CFE1-4D46-AB1F-15F238437A3D}] 
AppID="{A440BD76-CFE1-4D46-AB1F-15F238437A3D}" 

;;; Capicom.HashedData - use same AppID for all!!!!! 
[HKEY_CLASSES_ROOT\CLSID\{CE32ABF6-475D-41F6-BF82-D27F03E3D38B}] 
AppID="{A440BD76-CFE1-4D46-AB1F-15F238437A3D}" 

Salva in un file myComponent-dllhost.reg, e si va via.

c:\windows\sysWow64\regedit.exe "myComponent-dllhost.reg" 

Ora dovreste essere in grado di accedere a Capicom.HashedData e Capicom.EncryptedData da host script/COM a 64 bit.

Note:

  • Questo funziona solo per i tipi di base di automazione. Qualsiasi oggetto compatibile con gli script di Windows Scripting Host in VBScript o JavaScript dovrebbe essere OK.
  • È sufficiente aggiungere l'AppID agli oggetti direttamente creabili. Questo è fondamentalmente quelli con una voce InprocServer32. Gli oggetti generati dalle fabbriche o che sono disponibili solo come oggetti figlio non devono avere un AppID aggiunto.
  • Se è già disponibile un AppID, è sufficiente aggiungere la voce "DllSurrogate" a stringa vuota. Questo è tutto!
  • questo NON riguarda i client normali della DLL. Finché la bit-ness coincide, continueranno a essere caricate in-process come prima. L'unica differenza che farà è che sarà possibile istanziarlo fuori processo da un cliente di un diverso testimone.
+0

Ho già funzionato, ma mi sento riluttante a modificare la registrazione di altri componenti (in questo caso, Lotus Notes e Rational ClearCase) dal mio programma di installazione, quindi mi chiedo se c'è un modo per farlo senza modificare il registro . –

+2

Non essere timido! OTOH, se lo vuoi davvero, puoi creare un oggetto com helper dello stesso bitness, che ha solo un metodo 'HRESULT CreateObject ([in] BSTR progID, [out, retval] IUnknown ** ppRetVal)'. Avere quello crea l'oggetto all'interno del surrogato e restituirlo a voi. – Ben

+0

Questa è una buona idea. –

Problemi correlati