【问题标题】:Can I stop a COM dll from displaying forms?我可以阻止 COM dll 显示表单吗?
【发布时间】:2010-10-14 02:04:20
【问题描述】:

更具体:

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

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

有谁知道在 .Net 端捕获这些 UI 调用(可能是 form.show 而不是消息框)的方法,以便我们可以抛出异常?

【问题讨论】:

    标签: c# .net com vb6 interop


    【解决方案1】:

    需要注意的是我没有亲自这样做,我相信你想要的拦截和重定向可以通过Win32 Hooks来实现

    【讨论】:

    • 如果他不想深入研究 COM dlls 代码,我认为这是最好的解决方案,但它需要更多的工作!!
    • 我同意,今晚我手头有参考资料库时会更新。
    • 实际上可能没有更多的工作。旧版 Dll 是 10 多年前的保险应用程序的一部分,每个公司/评级日期和地区都有单独的 Dll。大约有 10,000 个图书馆!
    • 10,000 个图书馆!!!这太疯狂了!确定它可以由数据驱动吗? IE。从某个中心位置查找公司/评级/地区数据的 DLL 数量要少很多倍? mrdryden,我相信你已经想到了 - 有希望吗?
    【解决方案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 代码使用。事实上,这应该是一个测试。

    还请注意,这将是一个记录移植代码的好机会,这样在接下来的十年中这将不再是一个问题。只是不要丢失文档!

    【讨论】:

    • 哦,我多么希望这是一个选项。管理层不想放弃多年的评级规则,我也无法改变他们的想法。线程问题也是我非常关心的问题。
    • +1。一个线程的噩梦。顺便说一句,StackOverflow 上有一些关于将 VB6 转换为 VB.NET 的问题,以及有关其他资源(包括领先工具)的信息。您可以交叉引用它们。
    • 谢谢大家。你们俩都不知道自己离目标有多近。现在,我将不得不尝试用钩子来灭火,但迟早,这个选项可能会成为唯一的选择。管理不好吗?
    【解决方案3】:

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

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

    【讨论】:

      猜你喜欢
      • 2012-07-29
      • 1970-01-01
      • 1970-01-01
      • 2019-02-06
      • 2011-08-27
      • 2013-02-23
      • 1970-01-01
      • 1970-01-01
      • 2011-03-29
      相关资源
      最近更新 更多