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

C# 我可以阻止COM dll显示表单吗?,c#,.net,com,vb6,interop,C#,.net,Com,Vb6,Interop,更具体地说: 我们有一个web服务(用.Net编写),它使用大量COM DLL作为核心业务逻辑(用VB6编写)。现在假设这些是密封的库 不幸的是,这些COM库中的许多实现了自己的错误处理或验证消息;如果我们传入的数据不完整,或者缺少另一个COM依赖项,它们将显示一个对话框。这些对话框是问题所在…在IIS中运行时,这些消息框会挂起请求,等待用户单击“确定”以查看无法看到的框 有人知道如何在.Net端捕获这些UI调用(可能是form.show而不是messagebox),这样我们就可以抛出异常了吗?

更具体地说:

我们有一个web服务(用.Net编写),它使用大量COM DLL作为核心业务逻辑(用VB6编写)。现在假设这些是密封的库

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


有人知道如何在.Net端捕获这些UI调用(可能是form.show而不是messagebox),这样我们就可以抛出异常了吗?

,但我个人没有这样做,我相信,如果表单是用VB6编写并在桌面应用程序中使用的,那么通过显示表单就可以实现所需的拦截和重定向。这些COM对象可能也不希望被多个线程同时访问。这可能会非常壮观或非常微妙地爆炸

如果管理层依赖于此为10000个库工作,那么您需要让他们明白,违反10000条10年前的代码的假设不是一个好主意

如果管理层已经足够成熟了(在美国也是如此),那就让他们想起玛格琳的老广告“愚弄大自然是不好的”。坏事可能会发生


我想我需要更具体地描述“坏事情”

我假设这些是创建用于与VB6窗体应用程序交互的VB6 COM对象。这些COM对象可以合理地假设一次只有一个线程访问它们,一次只有一个用户访问它们,事实上,在它们的整个生命周期中只有一个线程和一个用户访问它们

一旦在服务器上运行它们,就违反了它们的假设

谁知道那会导致什么?没有人会做这种分析,因为它们是基本的(有效的)假设!代码是否会在线程本地存储中缓存某些内容?在最初的情况下,这是可行的。也许共享数据用于缓存信息。如果它将由多个线程使用,则需要进行联锁,然后您必须希望信息不会因每个用户而异,因为不同的线程可能代表不同的用户运行

有一次我被告知去修复一个内存泄漏。长话短说,这不是内存泄漏。它是一段遗留的非托管代码,假定它在桌面或批处理应用程序中运行。在web服务中,它将垃圾喷到了整个堆上。因此,它到处抛出异常,并导致其他不相关的代码也这样做。非托管异常没有太多细节,因此不可能看到是什么导致了问题,或者如何解决问题

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

如果COM对象都可以在一个用户身份下运行,这就为您省去了一点痛苦。除此之外,您可能只需要确保一次只有一个给定对象的实例,并且对它的所有访问都是序列化的。为此,请在VB.NET中使用SyncLock语句

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

这样的港口可能不像你想象的那么难。“复制、粘贴并修复编译器错误”在VB6和VB.NET之间运行良好。甚至还有一些工具可以提供帮助。但正是自动化测试使这一点变得切实可行。否则,你就有理由担心港口建设得有多好

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


还要注意的是,这将是一个很好的机会来记录正在移植的代码,这样在接下来的十年中问题就不会那么严重了。只是不要丢失文档

查看《msdn》杂志上杰西·卡普兰的一些文章。他的专栏名为CLR Inside Out。查找COM互操作文章。有关问题可在此处下载:


编辑:看起来卡普兰先生只是那个部分的临时撰稿人。对于互操作相关的建议,它仍然是一个很好的资源。

如果他不想深入研究COM DLL代码,但它需要更多的工作,我认为这是最好的解决方案!!我同意,今天晚上当我手头上有我的参考图书馆时,我会更新。实际上,可能不会有更多的工作。传统DLL是10多年前的保险应用程序的一部分,每个公司/评级日期和地区都有单独的DLL。大约有一万个图书馆!10000个图书馆!!!那太疯狂了!当然,它可以成为数据驱动的?也就是说,从某个中心位置查找公司/评级/地区数据的DLL要少很多倍?德莱顿先生,我相信你已经想到了-有希望吗?哦,我多么希望那是一个选择。管理层不想抛弃多年来的评级规则,我也不能改变他们的想法。线程问题也是我非常关心的问题。一场噩梦。顺便说一句,关于如何将VB6转换为VB.NET,以及其他资源(包括主要工具)的信息,在StackOverflow上存在一些问题。你们可以相互参照,谢谢你们。你们俩都没有我