Note that there are some explanatory texts on larger screens.

plurals
  1. POGetting missing component error in a VB6 application
    text
    copied!<p>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:</p> <p><img src="https://i.stack.imgur.com/KIWiJ.png" alt="enter image description here"></p> <p>I've seen errors like these before but typically it says which component is missing dependencies or is not registered properly.</p> <p>I ran it through Process Monitor and got the following files that it cannot find:</p> <p><img src="https://i.stack.imgur.com/6EM5Y.png" alt="enter image description here"></p> <p>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.</p> <p>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.</p> <p>It is worth noting that error occurs after the last line of VB6 code (in <code>Form_Unload</code> event) has fired. I know this because the last line is a message box that does appear.</p> <p><strong>Much, much later EDIT</strong>: 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. </p> <p>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:</p> <pre><code>' 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 ...' </code></pre> <p>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:</p> <pre><code>With moDelegateObject Set .ThirdPartyCtlHandler1 = Nothing Set .ThirdPartyCtlHandler2 = Nothing Set .ThirdPartyCtlHandler3 = Nothing End with Set moDelegateObject = Nothing </code></pre> <p>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. </p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload