【问题标题】:Getting missing component error in a VB6 application在 VB6 应用程序中出现缺少组件错误
【发布时间】:2012-02-04 05:03:12
【问题描述】:

我有一个包含大量第 3 方组件的 VB6 应用程序。该应用程序运行良好,但在退出时(并且仅在作为独立 EXE 运行时,例如不在 IDE 中),它会弹出一条错误消息:

我之前也看到过类似的错误,但通常会显示哪个组件缺少依赖项或未正确注册。

我通过 Process Monitor 运行它并获得了以下找不到的文件:

然后它就退出了。我用谷歌搜索了它找不到的文件名,似乎找不到任何东西。它似乎在寻找 MSComENU、MSComEN 和 MSCOENU dll 的变体。

我检查并重新检查以确保所有第 3 方组件都存在并且它们存在 - 应用程序功能正常,如果它们不存在则不会。

值得注意的是,VB6 代码的最后一行(在Form_Unload 事件中)触发后会发生错误。我知道这一点,因为最后一行是一个确实出现的消息框。

很久很久以后编辑:我终于重新开始处理这个问题,并通过消除过程解决了这个问题(这是一个漫长的过程)。最后,它与任何 MSCOMM*.dll 条目无关。事实上,我不知道为什么它们仍然出现在 Process Monitor 中。问题要简单得多。

我在主窗体上有几个第 3 方控件。为了不让大量事件处理代码污染主窗体,我将这些控件委托给一个新类,如下所示:

' declaration code in main form'
Private WithEvents moDelegateObject as clsDelegateObject

' still in the main form, after initialization'
Set moDelegateObject = new clsDelegateObject
With moDelegateObject
    Set .ThirdPartyCtlHandler1 = me.ThirdPartyCtl1
    Set .ThirdPartyCtlHandler2 = me.ThirdPartyCtl2
    Set .ThirdPartyCtlHandler3 = me.ThirdPartyCtl3
end with

' declarations and properties inside of clsDelegateObject'
Private WithEvents moThirdPartyCtlHandler1 as ThirdPartyCtl
Private WithEvents moThirdPartyCtlHandler2 as ThirdPartyCtl
Private WithEvents moThirdPartyCtlHandler3 as ThirdPartyCtl
Public Event FooEvent() ' other various events as well '

Public Property Set ThirdPartyCtlHandler1(o as ThirdPartyCtl) 
    moThirdPartyCtlHandler1 = o
End Property 
Public Property Get ThirdPartyCtlHandler1() as ThirdPartyCtl
    ThirdPartyCtlHandler1 = moThirdPartyCtlHandler1 
End Property
' ... Repeat for each handler ...'

缺少的是在关闭之前显式释放这些对象的代码。这是 Visual Basic 通常会做的事情。于是我在主窗体的Form_QueryClose中添加了以下内容:

With moDelegateObject
    Set .ThirdPartyCtlHandler1 = Nothing
    Set .ThirdPartyCtlHandler2 = Nothing
    Set .ThirdPartyCtlHandler3 = Nothing
End with
Set moDelegateObject = Nothing  

最后一行被证明是多余的,但为了完整起见,我把它扔在那里。我认为这是将控件委托给委托类并以 Main 形式从其接收事件以及使用大量真正晦涩难懂的 3rd 方控件的组合,这些控件导致了此问题。第 3 方控件很可能没有干净地释放自己。总之,吸取教训了。

【问题讨论】:

  • +1。 @anonymous close-voter:这是一个好问题。这些问题很难诊断,分享专业知识非常有用。
  • 这个问题是特定于一台计算机(开发机器?),还是在其他计算机上重复出现?它是否刚刚开始在以前运行良好的应用中发生?
  • 在我看来好像在美国英语机器/用户会话上运行的 MSComm32.dll 的外语版本中发生了一些错误(或只是 libload 失败),试图加载错误消息资源美国英语语言环境的 DLL。
  • @MarkJ 它可以在其他计算机上重复。奇怪的是,我有一个类似的应用程序,它具有完全相同的依赖项集,可以完美地安装和运行(安装构建也从同一位置绘制依赖项)。
  • @BobRiemersma 你是说MSCOMM32.OCX吗?因为我认为我没有在任何地方引用 MSCOMM32.DLL,MSCOMM32.OCX 也没有依赖它。

标签: vb6 error-handling


【解决方案1】:

这可能是 DLL_PROCESS_DETACH 或 CoUninitialize 问题。 Raymond Chen 的博客“The Old New Thing”有几篇相关文章:

正如您所说,这些是第 3 方组件。您可以尝试制作更小的测试用例,直到问题消失以查明有问题的组件。您还可以尝试使用本机代码调试器并分析生成错误消息的代码。

最简单的解决方案然而,要解决这个问题是尝试强制所有这些组件的特定加载顺序。在 Main() 或启动表单中,尝试以固定顺序使用每个 3rd 方组件的某些功能。如果错误仍然出现,请更改顺序,直到问题消失。这可能行得通。

【讨论】:

    【解决方案2】:

    您可以尝试在项目文件的引用列表中使用dependency walker,以查看这些第三方文件是否缺少依赖项。如果没有缺少依赖项,请尝试使用regsvr32 再次注册文件。如果任何 regsvr32 命令失败,那么您可能已经找到缺少依赖项的组件。

    【讨论】:

    • 还可以在重新注册组件之前先尝试取消注册 (regsvr32 /u [COMPONENT])。对我来说,这完成了一次。
    猜你喜欢
    • 2011-09-18
    • 1970-01-01
    • 1970-01-01
    • 2015-06-06
    • 2010-11-29
    • 1970-01-01
    • 2015-08-22
    • 2011-09-27
    • 2013-07-01
    相关资源
    最近更新 更多