Суррогат COM для стороннего компонента - PullRequest
10 голосов
/ 17 декабря 2011

Я пишу небольшой компонент DLL, которому требуется доступ к двум сторонним компонентам для объединения данных, один из которых является только 32-разрядным, а другой - только 64-разрядным.Оба зарегистрированы в TypeLib и совместимы с Automation, поэтому сортировка не должна быть проблемой.

Если я правильно понял документацию, то нет способа принудительно загрузить суррогат, если компонент не имеет AppIDи ключ DllSurrogate;так как оба являются сторонними компонентами, я несколько неохотно изменяю их регистрацию.

Есть ли способ активировать объект в компоненте без AppID в суррогатном процессе из компонента DLL, который в идеале некакие-нибудь дополнительные зависимости, или кто-нибудь может объяснить мне, почему это было бы плохой идеей?

1 Ответ

7 голосов
/ 17 января 2012

Да, вы можете загрузить (например) только 32-битную DLL в суррогат и получить к ней доступ из 64-битного процесса, следующим образом.Это будет работать при условии, что есть доступный маршаллер, который обычно будет для компонента с библиотекой типов, потому что они обычно используют стандартный маршаллер.Он не будет работать, если объект запрашивает пользовательский прокси / заглушку, потому что 64-битные версии не существуют, или у вас не возникло бы этой проблемы в первую очередь.

Сначала вам нужен AppID.Если у DLL уже есть AppID, вы должны использовать это.Это можно узнать, проверив под ключом CLSID интересующий вас CoClass.

В качестве примера здесь используются классы Capicom.HashedData и Capicom.EncryptedData.Capicom является только 32-разрядным.

Для этого следует использовать 32-разрядную версию Regedit, так как это 32-разрядный компонент.Если у вас есть 64-битный компонент, доступ к которому вы хотите получить из 32-битного, используйте другой.(Это связано с виртуализацией реестра для 32-битного уровня совместимости - использование соответствующей разрядной версии regedit позаботится об этой проблеме за вас, убедившись, что вы отредактировали правильную виртуализированную версию реестра).

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}"

Сохраните в myComponent-dllhost.reg файл, и все готово.

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

Теперь вы сможете получить доступ к Capicom.HashedData и Capicom.EncryptedData с 64-разрядных хостов сценариев / COM.

Примечания:

  • Это работает только для основных типов автоматизации OLE.Любой объект, совместимый со сценариями Windows Scripting Host в VBScript или JavaScript, должен быть в порядке.
  • Необходимо добавить AppID только для непосредственно создаваемых объектов.Это в основном те, у которых есть запись InprocServer32.Объекты, которые создаются на фабриках или доступны только как дочерние объекты, необязательно добавлять AppID.
  • Если уже существует AppID, все, что вам нужно сделать, это добавить запись "DllSurrogate" с пустой строкой.Вот и все!
  • это НЕ повлияет на обычных клиентов DLL.Пока битовость совпадает, они будут продолжать загружаться в процессе, как и раньше.Единственное отличие, которое он сделает, состоит в том, что станет возможным создать его вне процесса у клиента с другой битностью.
...