Мы разработали программную систему с использованием технологии ActiveX / COM (VB6) от Microsoft. В последний год меня все больше интересуют автоматизированные процессы сборки и SCM в целом. Я интенсивно искал в больших частях сети информацию о передовых методах выполнения scm с программными системами на основе COM.
«Проблема» с COM в том, что ссылающийся компонент хранит ссылку по уникальному идентификатору интерфейса. Когда вы перекомпилируете указанный компонент, идентификатор может измениться, и ссылка станет недействительной. Основная проблема здесь в том, что iid скомпилирован в двоичный файл. Поэтому, когда я не хочу возвращать скомпилированные файлы в систему контроля версий, каждый разработчик должен скомпилировать свои собственные версии и получить другие идентификаторы.
Когда я хочу проверить исходный код на чистой машине сборки для компиляции системы, это просто невозможно, потому что все ссылки недействительны (нет двоичных файлов, нет идентификаторов интерфейсов).
Мне просто интересно, если есть какие-то передовые практики, как настроить автоматизированную систему сборки для проектов COM (VB6)?
Редактировать: Да, мне известно о настройках совместимости. Но возьмем сценарий, в котором я хочу построить систему Wohle на чистой машине сборки без каких-либо двоичных файлов. Когда вы говорите, что проект бинарно совместим, вы должны предоставить бинарный файл, с которым проект совместим.
Я думаю, мне нужно написать собственный инструмент сборки, который изменяет ссылки и настройки совместимости в файлах проекта до и после компиляции проектов.
Поскольку VB6 / COM - действительно широко распространенная технология, я просто подумал, что должно быть готовое решение.
Обычно мы компилируем с двоичной совместимостью. Когда мы изменяем общедоступный интерфейс компонента, мы компилируем его с учетом совместимости проекта. Но когда вы меняете интерфейс базового компонента, который используется многими другими компонентами, вам нужно вручную изменить все ссылающиеся проекты на совместимость с проектами, перекомпилировать их и вернуться к двоичной совместимости. Это основной процесс, который я хочу автоматизировать.





Вы можете указать VB6 повторно использовать GUID (LIBID CLSID IID и т. д.), Изменив настройку совместимости проекта с «Нет совместимости» на «Двоичная совместимость». Вы можете найти эти настройки в Project-> Ваш-проект Properties. Параметр совместимости находится на вкладке «Компонент» в окне «Свойства проекта». Есть три варианта:
Вот что о них говорит MSDN:
No Compatibility
With this setting, no compatibility is enforced. Visual Basic creates new Interface IDs and Class IDs every time you build or compile your project. Each version built can only be used with applications created to work with that specific build of the component.Project Compatibility
With this setting, you can make your project compatible to a specific component project. While new type library information is generated, the type library identifier is maintained so that test projects can still refer to the component project. This setting is for maintaining compatibility during testing. Therefore, once the component is released, it behaves the same as the No Compatibility setting.
Binary Compatibility
When you compile your project, Visual Basic only creates new Class and Interface IDs when necessary. It preserves the class and interface IDs from the previous version(s) so that programs compiled using an earlier version will continue to work. If you are making a change that will result in an incompatible version, Visual Basic will warn you. If you want to maintain compatibility with older, released versions of an ActiveX component, this is the setting you need to use.
Похоже, вы сейчас компилируете с Нет совместимости. Как указано в статье MSDN, вам необходимо использовать Двоичная совместимость, чтобы новые версии ваших компонентов были совместимы со старыми версиями. Вы можете сделать это сейчас, выполнив следующие действия:
Скомпилируйте каждый проект один раз с помощью Нет совместимости
Сохраните эти «чистые» версии в папке, к которой люди, выполняющие сборки, могут легко получить доступ, например в сетевой ресурс, или поместите их в систему управления версиями.
Вернитесь и измените все проекты на «Двоичная совместимость» и укажите в «Совместимый файл» соответствующую версию, которую вы только что сохранили в сети / в системе управления версиями (не указывайте совместимый файл на тот же путь, по которому вы компилируете проект в. Совместимый файл должен быть отдельной копией исходного компонента, который не изменится. Он существует только для того, чтобы VB мог скопировать идентификаторы из этого файла в ваш проект при его перекомпиляции).
Каждый раз, когда вы перекомпилируете свои проекты, они будут повторно использовать GUID из совместимых (исходных) версий компонентов.
Обновлено: как Джо упомянул в комментариях, вы также должны распознать, когда интерфейсы вашего класса изменились (то есть, когда интерфейс изменился достаточно, чтобы вы могли дольше поддерживать двоичную совместимость с предыдущими версиями). Когда это происходит, вы хотите полностью отказаться от предыдущих версий компонентов: перекомпилировать новую «чистую» версию (т.е. без совместимости) и использовать эту новую версию в качестве совместимого файла в будущих сборках. Однако важно отметить, что вам следует начинать заново только тогда, когда изменяются интерфейсы вашего класса (свойства и методы). Фактически, VB предупредит вас, когда проект больше не совместим с предыдущей версией компонента.
Там, где я работаю, мы склонны (ab) использовать режим «Нет совместимости» в большинстве наших проектов, даже если это не совсем правильный способ делать что-то (вы должен используете двоичную совместимость). В нашей компании это приобрело лень, потому что у нас есть инструмент автоматической сборки, который компилирует все наши проекты за нас, и одна из основных функций этого инструмента заключается в том, что он может автоматически восстанавливать поврежденные ссылки на проекты между проектами. Поскольку инструмент сборки исправляет это за нас, у нас меньше стимулов использовать двоичную совместимость.
Несколько причин, по которым двоичная совместимость обычно является лучшим выбором:
Microsoft так говорит
Если все ваши компоненты бинарно совместимы с предыдущими выпусками вашего программного обеспечения, вы можете легко перекомпилировать один компонент и распространить его среди своих клиентов. Это упрощает развертывание исправлений / патчей. Если вы используете «Нет совместимости» в своих проектах, вам придется перекомпилировать и перераспределять все приложение каждый раз, когда требуется выход небольшого патча, потому что новые компоненты (вероятно) не будут работать со старыми компонентами.
Вы вносите свой вклад в соблюдение стандарта COM: в COM идентификаторы класса и интерфейса должны однозначно идентифицировать класс или интерфейс. Если ваши классы и / или интерфейсы не изменились между сборками, то нет причин создавать новые идентификаторы для этих классов и интерфейсов (фактически, тогда один и тот же класс будет иметь несколько идентификаторов). Двоичная совместимость позволяет вам поддерживать одни и те же идентификаторы в разных сборках, что означает, что вы являетесь хорошим гражданином и следуете соглашениям COM.
Меньше шума реестра. Если вы всегда развертываете для клиентов новые компоненты, которые не совместимы со старыми версиями на двоичном уровне, каждая новая версия будет добавлять новую информацию в реестр. Каждый новый интерфейс и идентификатор класса, помимо прочего, должны быть зарегистрированы. Если вы сохраните все двоично-совместимым, то установщику нужно будет только добавить ключи реестра в одном месте, поскольку идентификаторы вашего класса и интерфейса не изменятся.
Если вы раскрываете общедоступный API или компонент, который используют другие сторонние приложения, вам обязательно нужно использовать двоичную совместимость, чтобы не нарушать работу стороннего программного обеспечения, которое зависит от вашего кода.
@ Джо: Я знал, что забыл кое-что упомянуть. Я добавлю это, спасибо ;-)
Когда вы настраиваете новую машину разработчика и получаете "Совместимые" библиотеки DLL из системы управления версиями, вы регистрируете совместимые библиотеки DLL. Или вам следует скопировать последнюю построенную dll с машины сборки, которая находится рядом с файлами .vbp, и зарегистрировать их перед открытием файла vbg?
Визуальная сборка Pro. Если вы все еще застряли в области VB6 и должны создавать профессиональные продукты, я настоятельно рекомендую вам изучить этот продукт. У него есть бесплатная пробная версия, и он стоит каждого пенни (плюс он неплохо справляется с непрерывной интеграцией для .Net и других платформ). Он спасал нас от ада DLL в каждом выпуске с тех пор, как мы начали его использовать. Я не знаю другого способа создать достойную сборку на VB6.
Спасибо, Крис. Это действительно похоже на инструмент, который я искал. Я попробую, прежде чем писать свой собственный!
На самом деле довольно легко развернуть свой собственный (я создал инструмент сборки, который мы сейчас используем на работе, менее чем за день), если вам просто нужно что-то, что автоматически компилирует набор проектов и исправляет ссылки в процессе. Не так полно, как Visual Build Pro, но писать было весело ;-)
Как предлагает Майк Спросс, вам следует использовать двоичную совместимость. Вы можете (и должны) строить на чистой машине. Вы делаете это, сохраняя копию текущих производственных двоичных файлов (ActiveX DLL и OCX) в «совместимом» каталоге в вашей системе управления версиями. Все проекты должны ссылаться на эту копию, когда вы выбираете двоичную совместимость. Например, поместите новые двоичные файлы в ... \ Release, а совместимые двоичные файлы будут находиться в ... \ Compatible. Когда новая версия поступает в производство, вы копируете все из ... \ Release в ... \ Compatible. Таким образом, вы сохраняете совместимость от одного выпуска к другому.
В режиме двоичной совместимости VB создаст новый IID, если вы добавите новый метод в свой класс. Помните, что в COM интерфейс неизменен. Если вы вносите малейшие изменения в интерфейс, вы создаете что-то новое. VB соблюдает это правило COM, но использует дым и зеркала для предотвращения взлома старого клиентского кода. Поскольку VB «знает», что новый интерфейс является 100% надмножеством старого интерфейса (это то, что обеспечивает двоичная совместимость), он может использовать «перенаправление интерфейса». Перенаправление интерфейса просто перенаправляет все ссылки со старого интерфейса на новый интерфейс. Без этого трюка вам пришлось бы создавать новые версии (с другими именами и идентификаторами CLSID) любого компонента ActiveX, который вы изменяете. DLL Hell превратится в DLL Armargeddon!
VB хранит всю информацию о перенаправлении интерфейса в ресурсах вашего компонента. Когда вы регистрируете компонент, он записывает все IID интерфейса в HKCR \ Interface. Старые интерфейсы будут содержать информацию о пересылке. Только «реальный» интерфейс будет относиться к фактическому компонентному классу.
+1 за вникание в более технические детали того, как двоичная совместимость реализована в VB6.
+1, совершенно верно, следует использовать двоичную совместимость. Но затем у вас должен быть процесс, когда вы меняете свои интерфейсы, то есть перестраиваете чистую версию и снова сохраняете в Source Control, распознавая, когда вы нарушили обратную совместимость.