如何在.NET项目中使用Reg-Free COM引用vb6 DLL的Reg-Free COM?

5
我已经尝试很长时间解决这个问题,但是似乎没有任何作用。
我有一个用VB6编写的COM DLL。我在.NET中添加对此DLL的引用,并将“隔离”和“复制本地”属性设置为引用为真。显然这应该启用无需注册的COM。
但是它不起作用。如果我在另一台计算机上尝试,或者使用regsvr32取消注册DLL,尝试访问DLL会抛出异常(基本上说所需的com类不存在)。DLL和清单文件与EXE位于同一文件夹中,但它明显完全忽略它们。
我做错了什么?我阅读了大量关于此问题的散乱文章,但其中没有一个给我提供一个有效的解决方案。我曾经调整过Visual Studio,但无济于事。我稍微调整了一下make-my-manifest,但它并没有起作用(即使在测试项目上也是如此)。
4个回答

4

我正在非UI线程上创建和使用COM类。显然,对于VB6 DLL的Reg-Free COM,在这种情况下不起作用。以下测试代码可以证明:

Private Sub RunTest() Handles Button1.Click
    Try
        Dim x As New RegTestProject.RegTestCall
        MsgBox(x.RegTestFunction())
    Catch ex As Exception
        MsgBox(ex.ToString)
    End Try
End Sub

Private Sub RunThreadedTest() Handles Button2.Click
    'fails if reg-free COM is used'
    Dim t As New Threading.Thread(AddressOf RunTest)
    t.Start()
End Sub

当我使用正常注册的DLL运行时,两个测试都成功了。如果我使用无需注册的COM,线程测试就会失败,尽管正常测试仍然成功。看起来这将是一个非常麻烦的绕过方法。


你是否曾经发现这是否与非 UI 线程默认创建为 MTA 而不是 STA 线程有关? - Wil P
不,我只是通过确保所有的COM调用都来自UI线程来解决了这个问题。我向微软报告了这个问题,有人在那里提供了一个修复测试dll的示例清单,但说这个问题不够重要,不打算修复。 - Craig Gidney
1
Strilanc的讨论链接:https://connect.microsoft.com/VisualStudio/feedback/details/457217/reg-free-com-fails-when-threaded#tabs - tofutim

3

我相信当你以这种方式引用COM组件时,每次构建都会发生COM组件导入。这意味着必须在每台将要构建项目的机器上以传统方式注册COM组件。


2
这里有一篇描述如何使用无需注册的COM互操作的链接。如果您已经完成了这个步骤,请发布您的清单文件。您可能会因为错字而出现问题。 编辑 想到一个更简单的方法,只需在新机器上首次运行应用程序时注册DLL。无需注册的COM互操作仅适用于Windows XP及更高版本,因此如果您的目标是任何古老的系统,它将不起作用。

2
这是MSDN上有关reg-free COM的文章故障排除部分的摘录。如果您已经看过了,那么请原谅。好消息是您已经完成了其中一些步骤。建议在Windows Server 2003中(也许使用Virtual PC?)复制问题,然后事件日志应该会有所帮助。
首先让你的客户端与已注册的服务器配合工作;然后取消注册服务器并验证你期望的错误消息;最后制作和部署清单文件。这样,你的故障排除工作将仅限于清单文件的结构(如果选择这样做,则还包括程序集清单的正确嵌入)。
在故障排除无需注册的COM问题时,Windows Server 2003上的事件查看器是你的好帮手……查看系统事件日志查找来自COM服务器的事件。我不建议查看Windows XP事件日志……它通常包含一条无法帮助识别问题的消息。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接