【问题标题】:Installing com-enabled .net assembly onto Windows Terminal Server在 Windows 终端服务器上安装支持 com 的 .net 程序集
【发布时间】:2012-09-15 04:30:07
【问题描述】:

我有一个用 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 目录的读取和执行权限,但没有成功……请问有什么想法吗?

更新

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

【问题讨论】:

标签: .net vb.net visual-studio-2010 com terminal-services


【解决方案1】:

好的,首先,我发现 .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"

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

【讨论】:

  • 感谢您提及 System.Runtime.InteropServices.COMException
  • 1.是的,我做到了。 2. 不,我不使用微星。只需 xcopy 部署整个项目目录并尝试手动/使用 VS 帮助注册它 3. 我究竟如何“确保”它?不,早期绑定不是一种选择。 4. 我不相信 64/32 难题在这里有问题 - 如果在注册的同一用户中运行,它会完美运行。另请参阅更新
  • 我对这些问题的回退是打开 MS Access/Excel 并创建一个 VBA 模块。然后我转到“引用”以确认 .net COM dll 引用在列表中正确可用。有时您必须浏览到创建的 *.tlb 文件(不是 DLL)。如果这在 VBA 中可以正常工作,那么 CreateObject("Namespace.Class") 应该可以在您想要的任何环境中工作,请参阅 social.msdn.microsoft.com/Forums/pl/isvvba/thread/… 以快速了解该技术。
  • 是的,该库在两个用户帐户下的 VBA 的“参考”对话框中都可用。但是,它并没有自动包含在内 - 需要手动添加。
  • 我创建了一个简单的库和 COM 类来测试进程,并在获得正确的注册表信息后发现了您所面临的相同“ActiveX”异常。这意味着自从我使用生产产品以来,操作系统中发生了一些变化。将进一步调查。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多