在 Excel VBA 中调用没有管理权限的 COM 互操作 regasm

Posted

技术标签:

【中文标题】在 Excel VBA 中调用没有管理权限的 COM 互操作 regasm【英文标题】:Calling regasm without administrative rights for COM interop in Excel VBA 【发布时间】:2014-05-28 14:48:43 【问题描述】:

这里已经描述了在没有管理员权限的情况下调用 regasm 的解决方法:

COM Interop without regasm

我正在尝试创建一个 COM 库,我的用户可以在没有管理员权限的情况下从 Excel VBA 部署和使用该库。我喜欢 regasm 解决方法,因为似乎人们在使用 Excel VBA 中的免注册 COM 对象方面没有取得多大成功。我还希望提前绑定,以便我的用户可以从语法补全中受益。

但是,上述问题中接受的答案并未描述将程序集 dll 放在用户计算机上的哪个位置。在 GAC 中安装程序集需要管理员权限,所以我想知道可以将 dll 文件放在哪里。我假设正在搜索应用程序的目录以查找任何引用的 dll,但如果没有管理员权限,我无法将我的 dll 放入 Excel 的目录中。是否可以使用 Excel 客户端的解决方法?有没有其他方法可以从 VBA 调用 COM 对象而无需管理员权限先部署它们?

【问题讨论】:

【参考方案1】:

在没有 COM 互操作管理权限的情况下调用 regasm

我认为应该可以将RegistrationServices.RegisterAssemblyRegOverridePredefKey API 一起使用,以UAC 友好的方式在HKCU hive 下实现自动注册。我已经发布了更详细的答案here。

【讨论】:

这是一个有趣的想法。我试试看。 我写了一个简单的 C++/CLI 控制台应用程序并且它工作正常:int main(array<System::String ^> ^args) HKEY key; Console::WriteLine(RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("Software\\Classes"), 0, KEY_ALL_ACCESS, &key)); Console::WriteLine(RegOverridePredefKey(HKEY_CLASSES_ROOT, key)); auto rs = gcnew RegistrationServices; rs->RegisterAssembly(Assembly::LoadFile("C:\\lib-net.dll"), AssemblyRegistrationFlags::SetCodeBase); return 0; 【参考方案2】:

是的,现在你有两个问题,你不能把它放在应该放在任何地方,比如 GAC 或 c:\program 文件子目录。由于这些位置也需要 UAC 提升。您可能还忘记了运行带有 /codebase 选项的 Regasm.exe,需要告诉 CLR 在哪里查找文件。

用户需要有足够的权限才能将 DLL 复制到他具有写入权限的目录中。这通常只是 c:\users\username 中的一个目录,如 appdata 子目录。您必须解决的头痛问题是 .reg 文件需要针对每个用户进行调整,因为他的用户名不同。因此,需要为每个用户更改 .reg 文件中的CodeBase 值。委婉地说,这扩展性很差。

您找到的答案不是一个很好的答案。 真正有效的唯一解决方案是编写自己的注册函数。一种在 HKCU 而不是 HKLM 中写入注册表项的方法。使用[ComRegisterFunction] attribute。您可以从 .reg 文件中知道需要编写哪些键。并且您使用 Assembly.GetExecutingAssembly().Location 来确定为 CodeBase 注册表值编写的内容。不要忘记 [ComUnregisterFunction]。

请记住,至少在精神上,您正试图绕过 LAN 管理员对这些用户施加的限制。他们确实非常关心知道在他们支持的机器上运行什么样的代码。这很可能会给你带来麻烦,至少和那个人谈谈。

【讨论】:

我可以在代码库 reg 条目中使用环境变量,例如 %APPDATA% 吗?我总是可以编写一个安装脚本,将 DLL 复制到 %APPDATA% 并将 reg 文件中的一些占位符标记替换为用户应用程序数据目录的实际路径。你怎么看? @MichałFronczyk 也许 %UserProfile% 可以为你工作。 Related 所以基本上如果您不打算将.dll 存储在 GAC 中,那么您将/code 添加到regasm 命令行以便.tlb 知道您的.dll不在 GAC 中?

以上是关于在 Excel VBA 中调用没有管理权限的 COM 互操作 regasm的主要内容,如果未能解决你的问题,请参考以下文章

java 调用excel vba

求助!请教VBA高手! 有没有哪位高手有编制过调用翻译软件实现在excel中,英文译成中文的?

使用 Microsoft Excel VBA 仅查询访问 accdb 文件时,“MSysObjects”没有读取权限(错误编号:-2147217911) - mdb 工作正常

Excel-VBA - 在数据字段数组中插入新的第一列,无需循环或 API 调用

Excel 在VBA中可否调用winsock控件

从 Excel 调用 VBA 函数 - 在选定工作表上的选定列中查找