0

我有一个用 VB.NET (MSVS 2010) 编写的小类库,启用了“Com visible”和“Register for COM interop”标志。此库旨在用于 Windows 2008 终端服务器。我遇到了两个问题:

  1. 在服务器上注册我的库。显然,打电话regasm.exe my_lib.exe /tlb是不够的。虽然regasm确实将适当的键放入注册表,但调用 CreateObject("My_lib_prog_id")会导致失败。我通过在服务器上安装 MSVS2010 的试用版、以提升的权限运行它并在那里构建库来暂时解决了这个问题。而且效果很好,直到...

  2. 以另一个用户身份运行的 COM 客户端程序试图调用该库。它失败了。

编辑:“失败”意味着 VBA 在执行时抛出“系统找不到指定的文件”异常Set obj = CreateObject("MyLibProgID")。它在 Visual Studio 注册 lib 的同一用户帐户中工作正常。

我试图向每个人提供对 lib 目录的读取和执行访问权限,但它没有工作......有什么想法吗?

更新

如果客户端在任何其他用户下运行,即使该用户具有管理员权限,也会出现问题。

4

1 回答 1

2

好的,首先,我发现 .net COM dll 与 VBA 交互存在许多问题。

首先,通过属性在 .net 中配置它们,因此在注册表中正确配置它们很重要。确保 Dll 项目已标记为注册 COM 互操作。

其次,如果您使用 MSI 项目,请确保该软件已标记为“安装所有用户”。MSI 项目在删除注册表项方面做得很差,所以如果你搞砸了 MSI 安装、.net 版本等,你的服务器最终会出现“错误的注册表项”。我最终使用 regasm.exe 正确注册组件。我最终转向 WIX 项目安装。

第三,对于终端服务器,您需要确保注册表条目是“机器/全局”范围的,因为每个用户将运行一组可能不同的“注册表”条目。如果您正确设置了命名空间,您应该能够在 VBA 中进行早期绑定,而不是风险更高的后期绑定“CreateObject”调用。只需确保 VBA 在启动期间检查“损坏的引用”即可。

第四,我使用一个非常干净的 VM 来测试我的安装和注册表项,在 MS Office VBA 参考的帮助下,确认 COM 部分已正确注册,因此“CreateObject”调用不会失败。

第五,注意终端服务器的 x86/x64 问题以及您运行的显式 Office 版本(尤其是 Office 2010 x64)。如果服务器是 x64,您可能必须显式使用编译器标志 /86(任何 CPU 都可能对 VBA .net COM 对象非常不利)。

第六,注意从 .net 向 COM 引发异常的方式。查看 System.Runtime.InteropServices.COMException 以了解正确的方法。

From cmd 
c:
cd C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727{or the edition your using}
COPY "\\Distribution Share\{YourCompany}\{Software}\{Edition}\{.net Com DLL name}.dll" "C:\Program Files\{YourCompany}\{Software}\{.net Com DLL name}.dll"
Regasm.exe "C:\Program Files\{YourCompany}\{Software}\{.net Com DLL name}.dll" /u
Regasm.exe "C:\Program Files\{YourCompany}\{Software}\{.net Com DLL name}.dll" /regfile:"C:\Program Files\{YourCompany}\{Software}\{.net Com DLL name}.reg" /codebase
cd C:\WINDOWS\System32\
Regedit.exe /s "C:\Program Files\{YourCompany}\{Software}\{.net Com DLL name}.reg"

然后,我仔细查看了生成的注册表文件,以确保它们位于正确的注册表配置单元中。

于 2012-10-02T00:20:54.607 回答