Версия файла и версия сборки - PullRequest
3 голосов
/ 10 сентября 2010

У меня есть библиотека .NET (FW 2.0), которая используется приложением COM (vb6), а также приложением .NET.

Зарегистрирован TLB, созданный для COM, версия которого состоит изпервые две цифры "сборочной версии".Например, версия сборки 1.2.5.7 становится версией 1.2 TLB.Это очень неудобно, потому что иногда я хотел бы изменить вторую цифру без необходимости перекомпилировать приложение vb6, но мне кажется, что мне нужно перекомпилировать при изменении версии TLB.

Итак, я начал исследоватьфайл / сборка, и попытался использовать версию файла, чтобы идентифицировать мои изменения, поддерживая постоянную версию сборки.

Это работает, как и ожидалось (то есть просто работает) с приложением .NET, но не так сVB6 один.Если какая-либо третья цифра отличается (например, версия сборки 1.0.0.0 / версия файла 1.0.2.0), каждый раз, когда я пытаюсь создать новый объект, я получаю «Ошибка автоматизации -2147024894 (0x80070002)».

Может кто-нибудь сказать мне, почему это происходит, и если есть какое-то решение?

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

Редактировать (2010-09-14): Странно, если я скомпилирую сверсия сборки 1.0.0.0, затем я получил «Ошибка автоматизации», даже если я перекомпилирую проект vb6.

Редактировать (снова 2010-09-14): После проверки с помощью ProcMon иFileMon, кажется, нет никакого доступа к файлам в коде нарушителя, только запросы реестра, большинство ссылающихся на другие версии DLL.Кажется, что пробуют все предыдущие версии от 1.0.0.0 (которая с самым новым кодом) до 1.0.1.3, но не следующую (1.0.2.0).На данный момент версия файла - 1.0.2.1, и она работает, если я установлю версию сборки на 1.0.2.1, перекомпилирую и зарегистрирую ее.

Редактировать (2010-09-15): При поиске версии 1.0.1.3 моей DLL-библиотеки .Net в GAC происходит три ошибки PATH_NOT_FOUND (в c: \ windows \ assembly \ GAC_32 , c: \ windows \ assembly \GAC_MSIL и c: \ windows \ assembly \ GAC ) Существуют некоторые другие ошибки (в основном NAME_NOT_FOUND), но, похоже, все они обнаружены после попытки нескольких вариантов.Кажется, проблема в том, что он ищет неправильную версию DLL.

Другое редактирование (2010-09-15, по-прежнему): Следуя совету Ганса Пассанта, я запустил нарушителякод с fuslogvw выполняется в фоновом режиме, и это важные строки, которые он выдает:

LOG: DisplayName = E_DataIndex, версия = 1.0.1.3, Culture = нейтральный, PublicKeyToken = c322af271028978e(Полностью определено)

LOG: Appbase = file: /// C: / Архив программ / Microsoft Visual Studio / VB98 /

LOG: AppName = VB6.EXE

LOG: Неудачный поиск в GAC.

Редактировать: Согласно ответу Ганса,Я рано связываю и изменил каждый Guid интерфейса.Кажется, это работает (да, я знаю, я должен был попробовать это раньше) ...

Редактировать (2010-09-17): Я нашел причину оригиналапроблема: я не отменил регистрацию TLB перед регистрацией нового и, поскольку я не менял UUID, он продолжал искать последнюю установленную версию.Конечно, моя система управления версиями не самая лучшая в мире, но, зная эти подводные камни, я буду продолжать ее использовать (пока я новичок в COM и .NET-взаимодействии).Поскольку «типы не совпадают», похоже, является еще одной не связанной проблемой, я удаляю информацию и, если мне не удается решить ее самостоятельно, я открою новый вопрос.

Ответы [ 2 ]

6 голосов
/ 10 сентября 2010

Управление версиями в COM - серьезное дело.Страшный DLL Ад всегда рядом.Одно из самых жестких правил заключается в том, что если вы изменяете открытый интерфейс вашего COM-компонента, то у вас есть , чтобы дать интерфейсу новый GUID.Это гарантирует, что клиент, скомпилированный с предыдущей версией библиотеки типов, не сможет случайно использовать новый интерфейс.

Несоблюдение этого правила приводит к очень трудным для диагностики проблем.Клиент сервера вызовет неправильный метод.Или правильный метод, но с неправильными аргументами.Результат никогда не бывает красивым, все может случиться.Если вам повезет, программа завершит работу с AccessViolation.Такого рода удачу трудно найти, но обычно это просто неисправности очень непостижимым образом.

Судя по вашему вопросу, вы не используете атрибут [Guid] в своих интерфейсах, но оставляете его на усмотрениекомпилятор для автоматического создания.Это делается с учетом, например, атрибута [AssemblyVersion].Другая версия автоматически генерирует другой GUID.Что на самом деле дальше, так это то, что DLL избегает ада на работе, ваша программа VB6 больше не может найти интерфейс.Вы получите предсказуемое сообщение об ошибке вместо случайного звонка в сорняки.Программа VB6 должна быть перекомпилирована для использования новой библиотеки типов.

Обратите внимание, что это скорее функция, а не ошибка.Вы можете сами управлять им, задав для интерфейсов атрибут [Guid], чтобы они больше не зависели от имени или версии сборки.Теперь вы должны вручную изменить его при смене интерфейса.И рано или поздно заплатит цену, если вы забудете это сделать.

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

1 голос
/ 13 сентября 2010

Это компилируется / запускается на 64-битной машине с Windows 7?

Перейдите в окно свойств проекта и попробуйте переключить «Platform Target» с «Any CPU» на «x86»


Попробуйте запустить средство очистки reg, такое как CCleaner, и удалите все записи реестра, указывающие на dll. У меня был редкий случай, когда два ключа с соответствующими сигнатурами попали в реестр и вручную отменили регистрацию / регистрацию нужных компонентов, никогда не имевших значения, пока плохие ключи не были очищены. Ссылки в проекте VS выглядели правильно (вы могли просматривать нужные файлы и добавлять их без ошибок), но в действительности указывали на «файлы-призраки» из неверного ключа реестра и умирали при каждом запуске / компиляции проекта.

...