2012-02-04 115 views
12

我有一個擁有大量第三方組件的VB6應用程序。該應用程序運作良好,但在退出時(且僅作爲一個獨立的EXE,如不是在IDE中運行時),它會彈出一個錯誤信息:在VB6應用程序中獲取丟失的組件錯誤

enter image description here

我見過這樣的錯誤,這些之前,但通常它說明哪些組件缺少依賴關係或未正確註冊。

我跑了通過過程監控,並得到了以下文件,它無法找到:

enter image description here

然後它退出。我搜索了它找不到的文件名,但似乎找不到任何東西。它似乎是在尋找MSComENU,MSComEN和MSCOENU dll的變種。

我檢查和複查,以確保所有的第三方組件在那裏,他們是 - 應用功能很好,它不會,如果他們不存在。

值得注意的是,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 

最後行竟然是superflous,但我把它扔在那裏的完整性的緣故。我認爲這是委託類委託控制的組合,並在主窗體中接收來自它的事件,並使用大量非常模糊的第三方控件來解決這個問題。第三方控制很可能不會乾淨地釋放自己。無論如何,經驗教訓。

+0

+1。 @anonymous close-voter:這是一個很好的問題。這些問題很難診斷,分享專業知識非常有用。 – MarkJ 2012-02-04 13:20:14

+0

這是特定於一臺計算機(開發計算機?)的問題,還是在其他計算機上可重複使用?它剛剛開始發生在以前一直工作正常的應用程序中嗎? – MarkJ 2012-02-04 13:22:52

+0

在我看來,好像在運行美國英語機器/用戶會話的MSComm32.dll的外語版本中發生錯誤(或只是libload失敗),試圖加載美國英語區域設置的錯誤消息資源DLL。 – Bob77 2012-02-05 18:42:38

回答

2

這可能是一個DLL_PROCESS_DETACH或CoUninitialize問題。 Raymond Chen的博客 「舊的新」 有幾個相關文章:

至於你說的這些都是第三方組件。您可以嘗試製作更小的測試用例,直到問題消失,找出錯誤的組件。您也可以嘗試使用本機代碼調試器,並分析創建錯誤消息的代碼。

最簡單的解決方案但是要解決此問題,試圖強制所有這些組件的特定加載順序。在Main()或啓動窗體中,嘗試按固定順序使用每個第三方組件的某些功能。如果錯誤仍然出現,請更改順序,直到問題消失。這可能會起作用。

2

您可以嘗試在項目文件中的引用列表上使用dependency walker,以查看是否有任何第三方文件缺少依賴關係。如果沒有依賴項丟失,請嘗試使用regsvr32重新註冊這些文件。如果任何regsvr32命令失敗,那麼您可能已找到缺少依賴關係的組件。

+0

也試着先註銷(regsvr32/u [COMPONENT]),註冊一個組件,對我來說這個工作只做過一次。 – Simon 2012-02-17 12:20:54

相關問題