Раньше у меня была COM-DLL Visual Basic (VB6) (назовем ее «dllouter»), которая ссылалась на другую COM-DLL Visual Basic (VB6) (назовем ее «dllinner») с интерфейсом «Интерфейс». "dllouter" загружает "dllinner" следующим образом:
Public objCom As dllinner.Interface
Set objCom = New dllinner.Interface
Когда версия "dllinner" изменилась, без изменений в "Интерфейсе", "dllouter" смог загрузить ее без проблем, без необходимости перекомпилировать ее.
После этого я заменил dllinner сборкой C# .NET (VS2015) с [assembly: ComVisible(true)] и перекомпилировал dllouter, все было нормально и работало.
Но если я заменю [assembly: AssemblyVersion("1.0.0")] на более новую версию, Set objCom = New dllinner.Interface выйдет из строя. Мне нужно перекомпилировать «dllouter» после обновления ссылки на новый «dllinner», чтобы он заработал.
Я заметил, что при сравнении файлов .vbp со ссылками на Visual Basic "dllinner" и .NET "dllinner" разница в версии, указанной после GUID:
Ссылка = * \ G {6B0651C5-5225-42A6-841F0322797E5018} # 1.0 # 0 # ...
Значение, выделенное полужирным шрифтом, обновляется для сборки .NET с новой версией сборки (например, 2.0), в то время как оно остается неизменным для ссылки на Visual Basic DLL (всегда 1.0, независимо от версии «dllinner»).
Таким образом, я попытался добавить свойство [assembly: TypeLibVersion(1,0)] в assemblyinfo.cs и тем самым «исправил» ссылку в .vbp, что означает, что выделенное жирным шрифтом значение остается равным 1.0, независимо от того, что такое AssemblyVersion.
Однако проблема не решена: «dllouter» по-прежнему не загружает «dllinner».
Есть ли способ решить эту проблему, избегая перекомпиляции "dllouter" при изменении версии "dllinner"?
Публичный интерфейс не изменяется между следующими версиями.
А вы установили CLSID и идентификаторы интерфейса?
Т.е. у каждого класса должен быть ComClassAttribute, который явно устанавливает идентификатор интерфейса (и CLSID, если он должен быть создан): msdn.microsoft.com/en-us/library/…
Если вы не установите их, компилятор сгенерирует их автоматически, и они будут разными для каждой версии. Для обеспечения совместимости вам необходимо установить для них те же значения, что и в предыдущей версии.
Проект .vbp будет постоянно помнить исходный библиотека типов (не сборку .net) до тех пор, пока вы не удалите и повторно не добавите его в VB6 ide. Библиотека типов - это файл с расширением .tlb.
@Ben Я добавил явный идентификатор: [Guid("7A0CDBEE-4897-400C-8B5F-5F06C20F98AB")] public interface Interface { ... } и перекомпилировал все, но проблема все еще существует. @Hans Passant Я удалил и повторно добавил ссылку на .tlb, проблема в том, что мне нужно делать это каждый раз, когда я меняю версию сборки .NET "dllinner".
Конечно, в изменении основной версии нет ничего тонкого. Ни в .NET, ни в COM. Вы делаете это только тогда, когда отправили меньшую версию. Это более серьезная проблема в COM, потому что не делать этого, рискуя разразиться адом DLL. Вы уже видели, как выглядит этот ад :)
@Ben Я тоже пропустил явный идентификатор перед классом [Guid("C0DC113C-3839-4427-8DA5-35D768AFF3D6")] partial class classInterface : Interface {}; в дополнение к идентификатору интерфейса. Теперь это работает. Интересно, хочешь ли ты ответить на вопрос, или я должен ответить на него сам.





Если вы хотите, чтобы видимая сборка COM была совместима с предыдущей версией, вы должны:
1) Убедитесь, что в интерфейсе не видно никаких изменений. Если есть изменения в развернутых интерфейсах, значит, ваш новый объект несовместим, и вам придется сгенерировать новые идентификаторы CLSID, IID и новую библиотеку типов.
2) Убедитесь, что каждый видимый класс аннотирован IID, который такой же, как и в предыдущей версии. Если вы забыли сделать это в предыдущей версии, компилятор сгенерирует его для вас, поэтому вам нужно выяснить, что это было, чтобы новая версия могла быть такой же. Вы можете использовать TlbView или реестр, чтобы узнать это.
3) убедитесь, что каждый создаваемый класс аннотирован идентификатором CLSID, который совпадает с предыдущей версией.
Также неплохо проверить, что библиотека типов такая же. Вы можете декомпилировать предыдущую версию библиотеки типов с помощью TlbView или аналогичного инструмента, а затем сделать то же самое с новой версией. Вы не должны увидеть никаких существенных отличий.
Примечание. Если вы хотите добавить дополнительные функции, вы можете это сделать, но вам нужно создать новый IID для нового интерфейса, который должен наследовать от старого интерфейса (который должен быть помечен старым IID).
Если вы измените публичный интерфейс dllinner, это невозможно. Если вы этого не сделаете, это должно быть возможно.