Как связать DLL-библиотеки COM в портативное приложение?

Мне нужно написать программу, которая использует некоторые COM-объекты, доступ к которым осуществляется из пакета comtypes python. Я использую clsid и/или progid для их создания и использования. Эти объекты предоставляются третьей стороной и обычно устанавливаются с помощью обычного установщика (файл setup.exe или MSI).

Предположим, что у этих DLL-файлов есть лицензия, которая позволяет мне поставлять их вместе с моей программой. Можно ли загрузить эти DLL-файлы в память и использовать их из портативного приложения без фактической регистрации? Или, в качестве альтернативы, я могу зарегистрировать их из своей программы?

Связанный с этим вопрос: как определить цепочку файлов DLL, которые необходимы для создания данного COM-объекта? (Кроме проб и ошибок.)

Предыстория: на самом деле существует несколько библиотек, и основная проблема заключается в том, что я не хочу, чтобы пользователи запускали 4 разных установщика, прежде чем они смогут запустить реальную программу. Это было бы слишком сложно для обычного пользователя.


person nagylzs    schedule 26.08.2017    source источник


Ответы (1)


Вы задаете здесь много вопросов. Есть много способов добиться того, чего вы пытаетесь достичь, и трудно ответить на такой широкий набор вопросов. Если у вас есть конкретные вопросы о том, как сделать конкретную вещь, пожалуйста, начните новые сообщения для них.

Тем не менее, я постараюсь дать вам некоторую информацию, чтобы помочь вам понять, что вам нужно/хотите сделать.

Можно ли использовать COM-DLL без ее регистрации?

Да. Существует несколько способов, в зависимости от потребностей COM DLL и используемой вами платформы. Однако некоторые варианты не всегда будут работать, а другие варианты очень сложны.

  • DllGetClassObject — в В некоторых случаях, в зависимости от COM-объекта, который вы пытаетесь загрузить, вы можете просто загрузить DLL, вызвать DllGetClassObject напрямую и использовать возвращенную IClassFactory для создания объекта. Это самый простой способ - если он работает. Если класс, который вы создаете, требует, чтобы DLL была зарегистрирована (возможно, это делает CoCreateInstance внутренне, или, возможно, ему нужна поддержка прокси), это не сработает для вас. Чтобы определить, будет ли это работать, это либо метод проб и ошибок, либо вы должны спросить разработчика COM DLL.
  • COM без регистрации — так это делается в .NET. Я не уверен, что вы можете легко сделать что-то подобное в Python.
  • CoRegisterClassObject — если вы собираетесь создать свою собственную реализацию COM без регистрации, эта функция будет иметь решающее значение. Я считаю, что это фундаментальная деталь реализации COM без регистрации от Microsoft. Однако имейте в виду, что это будет очень сложно и потребует очень хорошего понимания COM.

Можете ли вы зарегистрировать COM-DLL из своей программы?

Да. Есть несколько способов. Однако здесь вы, скорее всего, столкнетесь с проблемами безопасности — обычно COM-компоненты регистрируются в HKEY_LOCAL_MACHINE, и вам обычно требуются права администратора для записи сюда. Некоторые COM-компоненты/установщики предназначены для регистрации в HKEY_CURRENT_USER, что позволяет обойти проблему безопасности. Однако у вас может не быть контроля над тем, где регистрируется компонент, и даже если вы это сделаете, регистрация в HKEY_CURRENT_USER не является идеальным решением.

  • regsvr32.exe. Одним из вариантов является программный вызов regsvr32.exe в библиотеке DLL.
  • DllRegisterServer или < a href="https://msdn.microsoft.com/en-us/library/windows/desktop/bb759846(v=vs.85).aspx" rel="nofollow noreferrer">DllInstall — если COM DLL можно зарегистрировать с помощью regsvr32.exe, тогда в ней будет экспортирована хотя бы одна из этих функций. Вы можете загрузить DLL вручную и вызывать эти функции так же, как это делает regsvr32.exe. DllInstall меньше чаще, чем DllRegisterServer . Если DllInstall присутствует, это может дать вам возможность установить в HKEY_CURRENT_USER. Если нет, вам нужно просто сделать что угодно DllRegisterServer делает, поскольку у этой функции нет опций.
  • Запишите значения реестра самостоятельно. Если вы можете определить все необходимые параметры реестра, ничто не мешает вам поместить их в реестр вручную. Это позволит обойти проблему HKEY_LOCAL_MACHINE/HKEY_CURRENT_USER — вы можете писать их где угодно (но HKEY_LOCAL_MACHINE все еще, вероятно, требует прав администратора).
  • regedit.exe — еще один способ самостоятельно записать значения реестра — сохранить их в файле .reg и вызвать regedit.exe для их объединения.

Как вы определяете зависимости DLL?

В идеале разработчик этой DLL знает и может рассказать вам. Это единственный способ, который действительно надежно защищен от дурака.

  • Для зависимостей COM может быть невозможно выяснить это каким-либо другим способом, кроме как спросить разработчика или методом проб и ошибок. Это связано с тем, что COM-зависимость может существовать просто потому, что некоторый код в DLL просто вызывает CoCreateInstance для создания стороннего COM-объекта, а поскольку это то, что выражено только в исходном коде, в DLL нет метаданных, которые помогут вам найти эти зависимости.
  • Вышеупомянутое также верно для любых динамически загружаемых зависимостей. Например, если какой-то код просто вызывает LoadLibrary напрямую, у вас нет возможности определить зависимость извне.
  • Для статически загружаемых зависимостей можно использовать такие инструменты, как Dependency Walker. Обратите внимание, что многие из зависимостей, которые вы увидите, являются системными — вы не хотите включать, например, user32.dll и kernel32.dll, потому что они устанавливаются вместе с Windows.

Как вы устанавливаете сторонние зависимости?

Если вы точно знаете, какие файлы записывать, куда их записывать и какие параметры реестра (и т. д.) необходимо применить, вы можете сделать все это самостоятельно. Для некоторых зависимостей может быть проще просто включить сторонний установщик в свой установщик и просто выполнить его без вывода сообщений. Именно по этой причине многие установщики поддерживают беззвучный режим. Хорошим примером этого является среда выполнения Visual C++ (msvcrt*.dll) — многие приложения нуждаются в этой зависимости, и многие установщики просто включают установщик Microsoft как часть своего дистрибутива, а основной установщик просто вызывает вторичные установщики без уведомления.

person Michael Gunter    schedule 29.08.2017