我需要编写一个使用某些COM对象的程序,可以从python comtypes包中访问。我使用clsid和/或progid来创建和使用它们。这些对象由第三方提供,通常使用普通安装程序(setup.exe或MSI文件)安装。
假设这些DLL文件的许可证允许我将它们与我的程序一起发送。是否可以将这些DLL文件加载到内存中,并在便携式应用程序中使用它们而无需实际注册它们?或者,我可以从我的程序中注册它们吗?
一个相关的问题是:如何确定创建给定COM对象所需的DLL文件链? (除了反复试验。)
背景:实际上,有多个库,主要问题是我不希望用户在启动实际程序之前运行4个不同的安装程序。对于普通用户来说,这太难了。
答案 0 :(得分:3)
你在这里问了很多问题。有很多方法可以完成你想要完成的任务,并且很难回答如此广泛的问题。如果您对如何做某件事有具体问题,请为这些人开始新的帖子。
那就是说,我会尽力给你一些信息,帮助你弄清楚你需要/想做什么。
是。有几种方法,具体取决于COM DLL和您正在使用的平台的需求。但是,某些选项并不总是有效,其他选项也非常具有挑战性。
DllGetClassObject
- 在某些情况下,根据您尝试加载的COM对象,您只需加载DLL,直接调用DllGetClassObject
函数,然后使用返回的{{3}创建你的对象。这是最简单的方法 - 如果有效的话。如果您创建的类要求注册DLL(可能在内部执行IClassFactory
,或者可能需要代理支持),这对您不起作用。要确定这是否有效,它可能是试错,或者您必须向开发人员询问COM DLL。CoCreateInstance
- 这是在.NET中完成的。我不确定你是否可以在Python中轻松做到这一点。是。有几种方法。但是,您可能会遇到安全问题 - 通常,COM组件在HKEY_LOCAL_MACHINE
中注册自己,并且您通常需要管理员权限才能在此处写入。一些COM组件/安装程序设计用于在HKEY_CURRENT_USER
中注册自己,这可以解决安全问题。但是,您可能无法控制组件注册的位置,即使您这样做,在HKEY_CURRENT_USER
中注册也不是一个完美的解决方案。
regsvr32.exe
- 一种选择是以编程方式调用DLL上的regsvr32.exe
。DllRegisterServer
- 如果可以向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的开发人员知道并且可以告诉您。这是真正万无一失的唯一方式。
DllRegisterServer
来创建一些第三方COM对象,并且因为这只是在源代码中表示的东西,所以没有元数据。 DLL将帮助您找到这些依赖项。LoadLibrary
,则无法从外部确定依赖关系。CoCreateInstance
之类的工具。请注意,您将看到很多依赖项是系统依赖项 - 您不希望包含例如user32.dll和kernel32.dll,因为它们随Windows一起安装。如果您确切地知道要写入哪些文件,在哪里编写它们以及需要应用哪些注册表设置(等等),您可以自己完成所有这些操作。对于某些依赖项,可以更轻松地在安装程序中包含第三方安装程序,然后以静默方式执行它。出于这个原因,许多安装程序支持静默模式。一个很好的例子是Visual C ++运行时(msvcrt * .dll) - 许多应用程序需要这种依赖关系,许多安装程序只是将Microsoft的安装程序作为其分发的一部分,而主安装程序只是静默调用辅助安装程序。 / p>