Получение ошибки отсутствующего компонента в приложении VB6 - PullRequest
12 голосов
/ 04 февраля 2012

У меня есть приложение VB6, в котором есть множество сторонних компонентов. Приложение работает хорошо, но при выходе (и только при запуске в качестве автономного EXE-файла, например, не в IDE) оно выдает сообщение об ошибке:

enter image description here

Я видел подобные ошибки раньше, но обычно в нем говорится, в каком компоненте отсутствуют зависимости или он не зарегистрирован должным образом.

Я запустил его через Process Monitor и получил следующие файлы, которые он не может найти:

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  

Последняя строка оказалась излишней, но я добавил ее для полноты картины. Я думаю, что это была комбинация делегирования элементов управления классу делегата и получения от него событий в главной форме и использования большого количества действительно неясных сторонних элементов управления, которые способствовали этой проблеме. Вероятно, что сторонний элемент управления не освобождает себя. Во всяком случае, урок усвоен.

Ответы [ 2 ]

2 голосов
/ 16 февраля 2012

Вы можете попробовать использовать обходчик зависимостей в списке ссылок в файле проекта, чтобы проверить, отсутствуют ли какие-либо из этих сторонних файлов зависимостей.Если зависимости отсутствуют, попробуйте зарегистрировать файлы еще раз, используя regsvr32 .Если какая-либо из команд regsvr32 завершится неудачно, возможно, вы обнаружили компонент с отсутствующими зависимостями.

2 голосов
/ 16 февраля 2012

Это может быть проблема DLL_PROCESS_DETACH или CoUninitialize.В блоге Рэймонда Чена "The Old New Thing" есть пара соответствующих статей:

Как вы сказали, это сторонние компоненты.Вы можете попытаться сделать меньшие тестовые случаи, пока проблема не исчезнет, ​​чтобы точно определить ошибочный компонент.Вы также можете попробовать отладчик встроенного кода и проанализировать, какой код создал сообщение об ошибке.

Самое простое решение , однако, чтобы обойти эту проблему, нужно принудительно установить определенный порядок загрузки всех этихкомпоненты.В форме Main () или при запуске попытайтесь использовать некоторые функции каждого стороннего компонента в фиксированном порядке.Если ошибка все еще появляется, меняйте порядок, пока проблема не исчезнет.Это может сработать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...