我有一个拥有大量第三方组件的VB6应用程序。该应用程序运行良好,但退出时(仅当作为独立的EXE运行时,例如不在IDE中),它会弹出一条错误消息:
我之前看到过这样的错误,但通常会说哪个组件缺少依赖项或未正确注册。
我通过Process Monitor运行它并获得了以下无法找到的文件:
然后退出。我用谷歌搜索了它找不到的文件名,似乎找不到任何东西。它似乎正在寻找MSComENU,MSComEN和MSCOENU dlls的变体。
我检查并重新检查以确保所有第三方组件都存在并且它们是 - 应用程序功能正常,如果它们不存在则不会。
值得注意的是,在VB6代码的最后一行(在Form_Unload
事件中)被触发后发生错误。我知道这是因为最后一行是一个确实出现的消息框。
很多,很久以后编辑:我终于回过头来处理这个问题并通过淘汰过程找出它(这是一个漫长的过程)。最后它与任何MSCOMM * .dll条目无关。事实上,我不知道他们为什么还会出现在Process Monitor中。问题要简单得多。
我在主表单上有几个第三方控件。为了不用大量的事件处理代码污染主表单,我将这些控件委托给一个新类,如下所示:
' 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表单中接收事件并使用大量非常模糊的第三方控件导致此问题的组合。第三方控件很可能没有干净地解除分配。无论如何,经验教训。
答案 0 :(得分:2)
这可能是DLL_PROCESS_DETACH或CoUninitialize问题。 Raymond Chen的博客“The Old New Thing”有几篇相关的文章:
正如您所说,这些是第三方组件。您可以尝试制作较小的测试用例,直到问题消失为止,以确定有缺陷的组件。您还可以尝试使用本机代码调试器并分析创建错误消息的代码。
最简单的解决方案但要解决此问题,请尝试强制所有这些组件的特定加载顺序。在Main()或启动表单中,尝试按固定顺序使用每个第三方组件的某些功能。如果仍然出现错误,请更改顺序,直到问题消失。这可能有用。
答案 1 :(得分:2)
您可以尝试在项目文件的引用列表中使用dependency walker,以查看是否有任何第三方文件缺少依赖项。如果没有缺少依赖项,请尝试使用regsvr32再次注册文件。如果任何regsvr32命令失败,那么您可能已找到缺少依赖项的组件。