«Недопустимый вызов процедуры или аргумент», но только в скомпилированном или P-Code EXE - PullRequest
2 голосов
/ 04 апреля 2010

У меня есть программа VB6, которую я поддерживаю в течение десяти лет. В программе есть подпрограмма «Prepare Copy», которая выглядит следующим образом (отредактировано для добавления изменений):

Public Sub PrepareCopy()

On Local Error GoTo PrepareCopyError

MsgBox "in modeldescription preparecopy"

Set CopiedShapes = New Collection

MsgBox "leaving preparecopy"
Exit Sub
PrepareCopyError:
    MsgBox Err.Description, , Err.Number
    Resume Next
End Sub

Где CopiedShapes недоступно для коллекции VB6.

Этот код теперь выбрасывает ошибку времени выполнения 5 - Недопустимый вызов процедуры или аргумент. Из кода промежуточной отладки следует, что ошибка возникает между MsgBox "in modeldescription preparecopy" и MsgBox "leaving preparecopy" строками и что путь кода On Error никогда не выполняется.

Как только диалоговое окно Ошибка 5 очищено, , затем появляется диалоговое окно MsgBox "leaving preparecopy", после чего программа закрывается.

На моей машине для разработки и двух клиентских компьютерах так себя ведет.

Это происходит только в коде времени выполнения и, похоже, не имеет значения, скомпилирую ли я его или использую P-код

То, о чем я здесь прошу, - это спекуляции относительно того, что вызывает подобные вещи.

Ответы [ 3 ]

3 голосов
/ 13 апреля 2010

Procmon не помог. Microsoft взяла глубокий образ системы в момент возникновения проблемы.

Они нашли неверный код ошибки HRESULT. Что-то глубоко во время выполнения VB6 пыталось получить доступ к объекту с поздней привязкой, но не объявленному через интерфейс IDispatch. Они быстро запланировали звонок со мной. Я спросил, какой объект вызывается через IDispatch; в частях VB6 моего проекта нет вызовов с поздним связыванием. («явная опция»)

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

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

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

Однако, если вы вызываете MsgBox из среды выполнения VB6, он отправляет WM_USER сообщения другим формам VB6 в проекте. Что, в свою очередь, в моем случае вызвало MDIForm_Activate, в котором был этот код:

Me.TreeView1.SetFocus

И это, несмотря на то, что TreeView1 по определению был объявлен явно, было тем, что они объявили как причину неудачного вызова IDispatch с поздним связыванием, в то же время отказываясь объяснять, как это могло быть. Парень по телефону даже зашёл так далеко, что сказал, что абсолютно может это выяснить, но политика Microsoft запретила это, потому что это VB6.

Удаление вызова SetFocus устранило обстоятельство, вызвавшее ошибку.

2 голосов
/ 05 апреля 2010

Ваш недавний комментарий говорит, что переменная Public CopiedShapes as New Collection.

  1. Не могли бы вы попробовать удалить new в объявлении?

  2. Есть ли в коллекции экземпляры с Sub Class_Terminate(), которые вызываются, когда старая коллекция собирается вместе с ее содержимым?

0 голосов
/ 04 апреля 2010

Ошибка возникает только на компьютерах, отличных от того, где был скомпилирован код? Возможно, в среде выполнения отсутствуют некоторые библиотеки DLL (например, MSVBRT.dll и т. П.).
Самый простой способ понять это: запустить на сборочной машине.

Если этого не происходит, вы можете создать развертываемую версию (установщик) через VB6), которая будет включать в себя все, что нужно. ИЛИ, используйте Procmon SysInternals, чтобы отслеживать процесс во время его выполнения и видеть, к какому ресурсу (файлу, DLL, ключу reg) он пытается получить доступ во время ошибки.

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