如何将COM dll捆绑到便携式应用程序中?

时间:2017-08-26 08:50:41

标签: python-3.x com dllregistration portable-applications comtypes

我需要编写一个使用某些COM对象的程序,可以从python comtypes包中访问。我使用clsid和/或progid来创建和使用它们。这些对象由第三方提供,通常使用普通安装程序(setup.exe或MSI文件)安装。

假设这些DLL文件的许可证允许我将它们与我的程序一起发送。是否可以将这些DLL文件加载到内存中,并在便携式应用程序中使用它们而无需实际注册它们?或者,我可以从我的程序中注册它们吗?

一个相关的问题是:如何确定创建给定COM对象所需的DLL文件链? (除了反复试验。)

背景:实际上,有多个库,主要问题是我不希望用户在启动实际程序之前运行4个不同的安装程序。对于普通用户来说,这太难了。

1 个答案:

答案 0 :(得分:3)

你在这里问了很多问题。有很多方法可以完成你想要完成的任务,并且很难回答如此广泛的问题。如果您对如何做某件事有具体问题,请为这些人开始新的帖子。

那就是说,我会尽力给你一些信息,帮助你弄清楚你需要/想做什么。

你可以在没有注册的情况下使用COM DLL吗?

是。有几种方法,具体取决于COM DLL和您正在使用的平台的需求。但是,某些选项并不总是有效,其他选项也非常具有挑战性。

  • DllGetClassObject - 在某些情况下,根据您尝试加载的COM对象,您只需加载DLL,直接调用DllGetClassObject函数,然后使用返回的{{3}创建你的对象。这是最简单的方法 - 如果有效的话。如果您创建的类要求注册DLL(可能在内部执行IClassFactory,或者可能需要代理支持),这对您不起作用。要确定这是否有效,它可能是试错,或者您必须向开发人员询问COM DLL。
  • CoCreateInstance - 这是在.NET中完成的。我不确定你是否可以在Python中轻松做到这一点。
  • Registration-free COM - 如果您要创建自己的免注册COM实现,此功能将至关重要。我相信这是微软免注册COM的基本实现细节。但是,请注意,这将是非常具有挑战性的事情,并且需要非常对COM的理解。

您可以从程序中注册COM DLL吗?

是。有几种方法。但是,您可能会遇到安全问题 - 通常,COM组件在HKEY_LOCAL_MACHINE中注册自己,并且您通常需要管理员权限才能在此处写入。一些COM组件/安装程序设计用于在HKEY_CURRENT_USER中注册自己,这可以解决安全问题。但是,您可能无法控制组件注册的位置,即使您这样做,在HKEY_CURRENT_USER中注册也不是一个完美的解决方案。

  • regsvr32.exe - 一种选择是以编程方式调用DLL上的regsvr32.exe
  • CoRegisterClassObjectDllRegisterServer - 如果可以向regsvr32.exe注册COM DLL,则至少导出其中一个这样的函数。您可以手动加载DLL并像regsvr32.exe一样调用这些函数。 DllInstall不像DllInstall那么常见。如果存在DllRegisterServer,则可以选择在HKEY_CURRENT_USER中安装。如果没有,你必须做DllInstall所做的任何事情,因为你没有可以提供给该功能的选项。
  • 自己编写注册表值 - 如果您可以找出所需的所有注册表设置,那么没有什么可以阻止您手动将它们放入注册表中。这可以解决HKEY_LOCAL_MACHINE / HKEY_CURRENT_USER问题 - 您可以在任何地方编写它们(但HKEY_LOCAL_MACHINE仍可能需要管理员权限。)
  • regedit.exe - 自己编写注册表值的另一种方法是将它们存储在.reg文件中并调用regedit.exe来合并它们。

如何确定DLL的依赖关系?

理想情况下,该DLL的开发人员知道并且可以告诉您。这是真正万无一失的唯一方式。

  • 对于COM依赖项,除了询问开发人员或反复试验之外,可能无法以任何其他方式解决这个问题。这是因为COM依赖关系可能只是因为DLL中的某些代码只是调用DllRegisterServer来创建一些第三方COM对象,并且因为这只是在源代码中表示的东西,所以没有元数据。 DLL将帮助您找到这些依赖项。
  • 以上情况也适用于任何动态加载的依赖项。例如,如果某些代码直接调用LoadLibrary,则无法从外部确定依赖关系。
  • 对于静态加载的依赖项,您可以使用CoCreateInstance之类的工具。请注意,您将看到很多依赖项是系统依赖项 - 您不希望包含例如user32.dll和kernel32.dll,因为它们随Windows一起安装。

如何安装第三方依赖项?

如果您确切地知道要写入哪些文件,在哪里编写它们以及需要应用哪些注册表设置(等等),您可以自己完成所有这些操作。对于某些依赖项,可以更轻松地在安装程序中包含第三方安装程序,然后以静默方式执行它。出于这个原因,许多安装程序支持静默模式。一个很好的例子是Visual C ++运行时(msvcrt * .dll) - 许多应用程序需要这种依赖关系,许多安装程序只是将Microsoft的安装程序作为其分发的一部分,而主安装程序只是静默调用辅助安装程序。 / p>