Регистрация COM-объекта - допустимо несколько?

У меня есть два COM-объекта с разными значениями GUID, но с тем же именем. Один из них - более новая версия другой. Что происходит, когда я регистрирую оба пользователя с помощью Name.exe/regserver? Я посмотрел в реестре, и они оба отображаются с тем же ProgID, но их соответствующие значения GUID отличаются. Они указывают на их отдельные места на жестком диске. Это проблема?

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

COM-объекты были созданы в VB6. Код, который их использует, - это С#. Они добавляются к отдельным проектам С# в качестве ссылок. Когда кто-то зарегистрирован, я не могу скомпилировать другой (и не запускать успешно).

Какая другая информация была бы полезной при расследовании этой проблемы?

3 ответа

Преобразование моего комментария в ответ:

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

Вы действительно должны изменить ProgID чтобы указать, что это эффективно новый компонент. Клиентским приложениям придется явно указывать на новый компонент или на старый. Люди часто просто добавляют номер версии (например, 2) в ProgId.


Вы нарушаете жесткие правила COM. Либо ваша замена должна быть точным совпадением с компонентом, который вы заменяете. Или вы должны создать новую версию, которая:

  • Использует другой [Guid] для coclass, вы сделали это правильно.
  • Использует другой ProgId, вы этого не делали. Boilerplate должен включать номер версии в самом ProgId. Таким образом, Foo.Bar становится Foo.Bar.2
  • Использует различные [Гиды] для интерфейсов, реализуемых классом. Это легко заметить, так как они хорошо скрыты в компоненте VB6. Решающий, однако, когда класс используется из другой квартиры. COM должен найти библиотеку типов для компонента, чтобы он знал, как маршалировать вызов метода интерфейса. Обязательно объявите свои интерфейсы явно в коде С#.

Лучший способ проверить все это, выполнив команду OleView.exe, File + View Typelib. Это декомпилирует содержимое библиотеки типов обратно в IDL, вы увидите подсказки и интерфейсы. Если вы хотите создать точную замену старого компонента, то все должно точно совпадать. Точные же концы, точно такие же интерфейсы с тем же самым порядком методов и точно такими же аргументами.


Я никогда не обращался к VB6 ActiveX exes из.NET (только DLL), так что это выстрел в темноте (и достаточно слаб, чтобы быть просто комментарием, за исключением того, что он слишком длинный).

Возможно, вы можете создавать/экспортировать.tlb каждый для двух компонентов VB6 для компиляции вашего С#. Вам не нужно использовать exes для компиляции.

Затем вручную добавьте записи реестра, как если бы у них были отдельные идентификаторы программы (например, MyComponent.ServerClass.1 и MyComponent.ServerClass.2), а затем загрузите их по имени на своем С#.

licensed under cc by-sa 3.0 with attribution.