2011-12-16 16 views
7

Estoy escribiendo un pequeño componente DLL que necesita acceder a dos componentes de terceros para combinar datos, uno de los cuales es de 32 bits solamente y el otro solo de 64 bits. Ambos están registrados con un TypeLib y son compatibles con Automation, por lo que la clasificación no debería ser un problema.sustituto COM para componente de terceros

Si entendí la documentación correctamente, entonces no hay forma de forzar la carga en un suplente a menos que el componente también tenga un AppID y la clave DllSurrogate; ya que ambos son componentes de terceros, soy un poco reacio a modificar su registro.

¿Hay alguna forma de activar un objeto en un componente sin un AppID en un proceso sustituto desde un componente DLL que idealmente no tiene dependencias adicionales, o alguien puede explicarme por qué sería una mala idea?

+1

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

+1

¿No sería un sustituto personalizado también requerir que el componente del servidor tenga un AppID, por lo que COM sabe qué sustituto crear una instancia de la clase en ? Si agrego eso, esto afectaría a todos los clientes, no solo a mi componente, que preferiría evitar (también, el sustituto estándar debería funcionar bien). –

+0

[Raymond Chen] (http://blogs.msdn.com/b/oldnewthing/archive/2009/02/12/9413816.aspx) sugiere que el Explorer puede de alguna manera objetos 'CoCreateInstance' que no están registrados con un * DllSurrogate * clave para que se creen en un sustituto - Me interesaría saber cómo. –

Respuesta

6

Sí, puede cargar una DLL (por ejemplo) de 32 bits en un sustituto y acceder a ella desde un proceso de 64 bits, de la siguiente manera. Esto funcionará siempre que haya un Marshaller disponible, que generalmente será para un componente con un typelib porque generalmente usan el Marshaller estándar. No funcionará si el objeto requiere un prox/stub personalizado porque las versiones de 64 bits no existirán, o no tendría este problema en primer lugar.

Primero necesita un AppID. Si el archivo DLL ya tiene un ID de aplicación, debe usar eso. Puede averiguarlo marcando debajo de la clave CLSID para la CoClass que le interese.

El ejemplo utilizado aquí es Capicom.HashedData y Capicom.EncryptedData clases. Capicom es solo de 32 bits.

Debe utilizar la versión de 32 bits de Regedit para hacer esto, ya que es un componente de 32 bits. Si tiene un componente de 64 bits al que desea acceder desde 32 bits, use el otro. (Esto se debe a la virtualización del registro para la capa de compatibilidad de 32 bits; si utiliza la versión de bits correspondiente de regedit, se ocupa de este problema, al asegurarse de editar la versión virtualizada correcta 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}" 

guardar en un archivo myComponent-dllhost.reg, y ya está.

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

Ahora debería ser capaz de acceder Capicom.HashedData y Capicom.EncryptedData de los anfitriones script/COM de 64 bits.

Notas:

  • Esto sólo funciona para los tipos básicos de automatización OLE. Cualquier objeto compatible con las secuencias de comandos de Windows Scripting Host en VBScript o JavaScript debería estar bien.
  • Solo tiene que agregar el AppID a objetos directamente creables. Eso es básicamente aquellos con una entrada InprocServer32. Los objetos que se generan a partir de fábricas o que solo están disponibles como objetos secundarios no tienen que tener un AppID agregado.
  • Si ya hay un AppID, todo lo que necesita hacer es agregar la entrada de cadena vacía "DllSurrogate". ¡Eso es!
  • esto NOT afecta a los clientes normales de la DLL. Siempre que la bit-ness coincida, continuarán siendo cargados en proceso como antes. La única diferencia que hará es que será posible instanciarlo fuera de proceso de un cliente de bitness diferente.
+0

Ya lo tengo trabajando, pero me siento reacio a modificar el registro de otros componentes (en este caso, Lotus Notes y Rational ClearCase) de mi instalador, por lo tanto, me pregunto si hay una forma de hacerlo sin modificar el registro . –

+2

¡No seas tímido! OTOH, si realmente lo deseas, puedes crear un objeto com colaborador del mismo bitness, que solo tiene un método 'HRESULT CreateObject ([en] BSTR progID, [out, retval] IUnknown ** ppRetVal)'. Haga que eso cree el objeto dentro del sustituto y se lo devuelva. – Ben

+0

Esa es una buena idea. –

Cuestiones relacionadas