在 VB6 应用程序中出现缺少组件错误

发布于 2025-01-03 03:39:17 字数 2121 浏览 0 评论 0 原文

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

我以前见过类似的错误,但通常它表示哪个组件缺少依赖项或未正确注册。

我通过进程监视器运行它并得到了它找不到的以下文件:

在此处输入图像描述

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

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

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

很久很久以后编辑:我终于回到处理问题并通过排除过程找到了它(这是一个漫长的过程)。最后它与任何 MSCOMM*.dll 条目无关。事实上,我不知道为什么它们仍然出现在进程监视器中。问题就简单多了。

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

' 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  

最后一行结果是多余的,但为了完整性我将其放在那里。我认为这是将控件委托给委托类并在主窗体中接收事件的组合,并使用了大量真正晦涩的第三方控件,这导致了这个问题。第三方控制很可能没有完全释放自己。无论如何,吸取教训了。

I have a VB6 app that has a ton of 3rd party components. The app works well, but on exit (and only when running as a standalone EXE, e.g. not in the IDE), it pops up an error message:

enter image description here

I've seen errors like these before but typically it says which component is missing dependencies or is not registered properly.

I ran it through Process Monitor and got the following files that it cannot find:

enter image description here

And then it quits. I googled the file names that it cannot find and can't seem to find anything. It seems like its searching for a variation of MSComENU, MSComEN and MSCOENU dlls.

I checked and rechecked to make sure that all the the 3rd party components are there and they are - the application functions fine, it wouldn't if they weren't there.

It is worth noting that error occurs after the last line of VB6 code (in Form_Unload event) has fired. I know this because the last line is a message box that does appear.

Much, much later EDIT: I finally got back to dealing with the problem and figured it out by process of elimination (and it was a loooong process). In the end it had nothing to do with any MSCOMM*.dll entries. In fact, I do not know why they still show up in Process Monitor. The problem was much simpler.

I had several 3rd party controls on the main form. In an effort not to pollute the main form with a ton of event handling code, I delegated these controls to a new class, like so:

' 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 ...'

What was missing was code to explicitly deallocate these objects prior to closing. This is something that Visual Basic typically does. So I added the following in the Form_QueryClose in the main form:

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

Last line turned out to be superflous, but I threw it in there for completeness sake. I think it was a combination of delegating controls to a delegate class and receiving events from it in the Main form and using a good number of really obscure 3rd party controls which contributed to this problem. It is probable that the 3rd party control does not cleanly deallocates itself. Anyway, lesson learned.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

别靠近我心 2025-01-10 03:39:17

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

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

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

This could be a DLL_PROCESS_DETACH or CoUninitialize problem. Raymond Chen's blog "The Old New Thing" has a couple of relevant articles:

As you said these are 3rd party components. You could try to make smaller test cases until the problem disappears to pinpoint the buggy component. You could also try a native code debugger and analyze what code created the error message.

The simplest solution however to work around the issue is trying to force a specific load-order of all those components. In the Main() or startup form, try to use some functionality of each 3rd party component in a fixed order. If the bug still appears, change the order until the problem vanishes. That might work.

无尽的现实 2025-01-10 03:39:17

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

You could try using dependency walker on the list of references in the project file to see if any of those third party files are missing dependencies. If no dependencies are missing then try registering the files again using regsvr32. If any of the regsvr32 commands fail then you may have found the component with missing dependencies.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文