我可以阻止COM dll显示表单吗?

时间:2009-03-18 13:49:11

标签: c# .net com vb6 interop

更具体一点:

我们有一个Web服务(用.Net编写),它利用大量的COM dll来实现核心业务逻辑(用VB6编写)。现在假设这些是密封的库。

不幸的是,许多这些COM库实现了自己的错误处理或验证消息;如果我们传入的数据不完整,或者缺少另一个COM依赖项,它们将显示一个对话框。这些对话框是问题...当在IIS中运行时,这些消息框挂起请求,等待用户单击确定到无法看到的框。

有没有人知道如何在.Net端捕获这些UI调用(可能是form.show而不是消息框),所以我们可以抛出异常?

3 个答案:

答案 0 :(得分:2)

虽然我个人没有这样做,但我相信你所希望的拦截和重定向可以通过Win32 Hooks

实现。

答案 1 :(得分:2)

如果使用VB6编写这些表单以便在桌面应用程序中使用,那么表单的显示是您遇到的最少问题。这些COM对象可能不希望同时被多个线程访问。这可能非常引人注目或非常巧妙。

如果管理层依赖于此工作来为10,000个图书馆工作,那么您需要让他们明白违反10,000个十年代码的假设并不是一个好主意。

如果管理层已经足够老了(并且在美国),那么请提醒他们旧的margerine商业广告中有关“它不是很好来愚弄大自然”。坏事可能会发生。


我认为我需要更加具体地讲述“坏事”。

我假设这些是为与VB6表单应用程序或应用程序交互而创建的VB6 COM对象。然后,这些COM对象可以合理地假设一次只有一个线程访问它们,一次只有一个用户访问它们,实际上只有一个线程和一个用户在整个生命周期内访问它们。

只要在服务器中运行它们,就会违反它们的假设。

谁能说出会导致什么?没有人会做那个分析,因为它们是基本的(和有效的)假设!代码是否可以缓存线程本地存储中的某些内容?这对原始场景有用。也许共享数据用于缓存信息。如果它被多个线程使用,它需要互锁,然后你必须希望信息不会因用户而异,因为不同的线程可能代表不同的用户运行。

我曾被告知要修复内存泄漏。长话短说,这不是内存泄漏。这是一段遗留的非托管代码,假设它在桌面或批处理应用程序中运行。在一个Web服务中,它在整个堆中喷出垃圾。因此,它在整个地方抛出异常,并导致其他不相关的代码也这样做。非托管异常没有详细说明,因此无法确定导致问题的原因或解决方法。

在这种情况下,我能够简单地在所有访问周围放置一个互锁。这很好,因为这段代码假定了一个批处理环境,而不是一个交互式环境。如果您的COM对象假设其十年的要求没有从它们下面改变,那么这可能是不够的。

如果COM对象都可以在单个用户身份下运行,那么可以为您节省一件悲伤。除此之外,您可能只需要确保一次只有一个给定对象的实例,并且所有对它的访问都是序列化的。在VB.NET中使用SyncLock语句。

最终的解决方案是执行代码的“测试驱动端口”。我会使用现有的代码库来创建自动单元测试(可能使用vbunit)。一旦代码具有足够的单元测试覆盖率,您就可以将该代码(仍作为COM对象)移植到VB.NET。单元测试可用于确认端口是否仍在工作。

这样的港口可能没有你想象的那么强硬。 “复制并粘贴并修复编译器错误”在VB6和VB.NET之间运行良好。甚至还有工具可以提供帮助。但这是自动化测试,使这变得实用。否则,你会非常担心端口的完成情况。

请注意,新的COM对象仍应由原始VB6代码使用。事实上,这应该是一个考验。

另请注意,这将是一个记录被移植代码的好机会,因此在未来十年内这不是一个问题。只是不要丢失文档!

答案 2 :(得分:0)

查看msdn杂志中Jesse Kaplan撰写的一些文章。他的专栏名为CLR Inside Out。查找COM Interop文章。可在此处下载问题:http://msdn.microsoft.com/en-us/magazine/cc159440.aspx

编辑:看起来卡普兰先生只是该部分的偶然撰稿人。它仍然是Interop相关建议的绝佳资源。