VB6 IDE аварийно завершает работу после завершения работы приложения

У нескольких разработчиков в моей команде есть эта проблема. Мы можем запустить наше приложение в среде IDE нормально, но когда мы в конечном итоге выйдем из приложения, тогда сама IDE выйдет из строя.

Авария принимает форму

"Visual Basic has stopped working"

VB6 IDE аварийно завершает работу после завершения работы приложения

Не имеет значения, закрываем ли мы приложение корректно или принудительно останавливаем его в отладчике; тот же результат (разбился IDE).


Последовательность выхода для приложения:

  1. Пользователь выбирает «выход» из меню

  2. Обработчик событий меню вызывает Unload Me

  3. Срабатывает обработчик событий Form_QueryUnload

  4. Срабатывает обработчик событий Form_Unload. Оно делает:

 

'close all sub forms
For i = Forms.Count - 1 To 1 Step -1
    Unload Forms(i)
Next

Затем сохраняет некоторые данные, а затем выполняет Exit Sub.


Мы обычно запускаем групповой файл, в котором содержится 5-6 проектов.

Иногда кажется, что эта ошибка исчезает, а иногда возникает случайным образом. Не знаю, какой фактор на это влияет.

Если мы на самом деле не запускаем приложение, а только IDE, тогда оно работает нормально, и мы можем выйти из самой IDE в обычном режиме.

Кто-нибудь видел это раньше? Любые идеи? Спасибо!

Я тоже видел это. Не очень часто и вроде бы случайно, как и вы. Я тоже не нашел решения.

Brian M Stafford 25.10.2018 19:24

Вы используете в проекте хуки API любой для сообщений Windows? Если это так, убедитесь, что они используются только в скомпилированном приложении нет в среде IDE.

John Eason 25.10.2018 19:32

Можете ли вы поделиться своим кодом выхода?

Bill Hileman 25.10.2018 21:11

FWIW, мне также интересно, что у вас есть «команда» разработчиков VB6. На самом деле приятно это слышать.

Bill Hileman 25.10.2018 21:13
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
4
271
2

Ответы 2

Это наиболее определенно вызвано утечками объектов VB6, которые участвуют в создании подклассов / подключений, и не только ими.

Чтобы избавиться от этих сбоев, мы оснастили все наши классы (включая формы, пользовательские элементы управления, конструкторы и все, что может быть создано) вызовами DebugInstanceInit и DebugInstanceTerm в соответствующих событиях Class / Form / UserControl Initialize и Terminate.

Public Sub DebugInstanceInit(sModuleName As String, sDebugID As String, oObj As Object)

Public Sub DebugInstanceTerm(sModuleName As String, sDebugID As String)

Они в основном отслеживают в любое время, сколько и какие экземпляры использует приложение. Каждому экземпляру назначается уникальный sDebugID в DebugInstanceInit, который используется в качестве ключа в коллекции DebugIDs. Эта коллекция создается пустой в Sub Main, и когда приложение завершается (то есть в Form_Unload основной формы), эта коллекция должна быть пустой или с фиксированным количеством оставшихся экземпляров (например, ровно 4), в противном случае ее содержимое является типом объектов, которые мы утекаем.

Что исправило сбои в IDE?

Обратите внимание, что коллекция создается так поздно, как Sub Main, что означает, что она должна оставаться Nothing во время разработки. Просто поставим простую проверку в DebugInstanceInit вот так

    If DebugIDs Is Nothing Then
        If Left$(sModuleName, 3) <> "ctx" Then
            DebugPrint "DebugInstanceInit", "mdErrorHandling", sDebugID & " " & LIB_NAME & "." & sModuleName & "." & FUNC_NAME_INITIALIZE & " (This should not happen)"
        End If
    Else
       ...
    End If

В основном это предотвращало создание экземпляров что-нибудь, отличных от необработанных пользовательских элементов управления, размещенных в формах, во время разработки. Сюда входят объекты GlobalMultiUse, сюда входят все, к чему имеют доступ свойства UC, поскольку свойства UC - это своего рода процедуры, к которым, безусловно, осуществляется доступ во время разработки.

Поэтому нам пришлось сильно опрыскать большую часть кода UC проверками Ambient.UserMode, подобными этой

    If Ambient.UserMode Then
        Set .Picture = LoadStdPicture(ucsPicHelp)
    End If

Оказалось, что наша глобальная функция LoadStdPicture, например, создавала экземпляр некоторого cDibSections. Приятно то, что как только вы устанавливаете точку останова в операторе отладочной печати (This should not happen), стек вызовов показывает вам именно вызывающее свойство нарушающего UC.

Я думаю, что этот ответ был правильным - оказалось, что проблема в моей конкретной программе возникла из сторонней библиотеки OCX; когда я обновил его до более новой версии, проблема была решена. Спасибо, что наставили меня на правильный путь.

StayOnTarget 07.11.2018 17:51

Также - я заметил несколько других подобных сообщений, которые вы сделали по этой теме, но я не уверен, включает ли какое-либо из них весь исходный код ваших очень полезных процедур DebugInstance ... (). Возможно, если вы добавите их сюда (или ссылку на полные источники), это будет полезно!

StayOnTarget 07.11.2018 17:52

@DaveInCaz Это может быть так же просто, как сгенерировать следующий последовательный идентификатор отладки и добавить информацию об экземпляре в коллекцию с "#" & sDebugID в качестве ключа (два LoC), а затем просто удалить ключ "#" & sDebugID при завершении (один LoC). Лучшим примером был бы целый проект с инструментальными классами и формами и msgbox с сообщением об утечках при разрыве приложения. . .

wqw 08.11.2018 08:34

Я считаю, что другой ответ правильно в своей технической оценке причины проблемы. Но также может быть полезно кратко описать процедуру, которую я использовал для сужения строк исходного кода. В моем случае эта проблема оказалась СОВЕРШЕННО случайной, поэтому было трудно понять, с чего начать.

Мой подход был не ракетостроением - скорее грубой силой. По сути, я использовал двоичный поиск, чтобы исключить / исключить участки кода. Первым шагом было закомментировать всю процедуру запуска, чтобы приложение запускалось как пустая оболочка; это продемонстрировало, что проблема исчезла (нулевой результат).

После этого я рекурсивно прокомментировал примерно половину кода, каждый раз проверяя проблему. Каждый блок оценивался как логическое значение - это либо создавало, либо не создавало проблемы. Затем продолжайте снова в блоке, который не исключен.

В конце концов (и быстрее, чем я ожидал) это привело к единственной строке кода, которая обращается к свойству стороннего элемента управления.

Другие вопросы по теме