Поделиться через


Обновление проектов

Изменения в модели проекта из одной версии Visual Studio в следующую может потребовать обновления проектов и решений, чтобы они могли работать в более новой версии. Пакет SDK Для Visual Studio предоставляет интерфейсы, которые можно использовать для реализации поддержки обновления в собственных проектах.

Стратегии обновления

Для поддержки обновления реализация системы проекта должна определять и реализовывать стратегию обновления. При определении стратегии можно выбрать поддержку параллельного резервного копирования (SxS), копирования резервных копий или обоих.

  • Резервное копирование SxS означает, что проект копирует только те файлы, которые нуждаются в обновлении на месте, добавляя подходящий суффикс имени файла, например "old".

  • Резервное копирование означает, что проект копирует все элементы проекта в указанное пользователем расположение резервного копирования. Затем обновляются соответствующие файлы в исходном расположении проекта.

Как работает обновление

Когда решение, созданное в более ранней версии Visual Studio, открывается в более новой версии, интегрированная среда разработки проверяет файл решения, чтобы определить, нужно ли обновить его. Если требуется обновление, мастер обновления автоматически запускается для прохождения пользователем процесса обновления.

Когда решение требует обновления, он запрашивает каждую фабрику проектов для своей стратегии обновления. Стратегия определяет, поддерживает ли фабрика проектов резервное копирование или резервное копирование SxS. Сведения отправляются в мастер обновления, который собирает сведения, необходимые для резервной копии, и представляет применимые параметры для пользователя.

Решения для нескольких проектов

Если решение содержит несколько проектов и стратегии обновления отличаются, например, если проект C++ поддерживает только резервное копирование с использованием SxS и веб-проект, поддерживающий только резервное копирование путем копирования, фабрики проектов должны согласовывать стратегию обновления.

Решение запрашивает каждую фабрику проектов для IVsProjectUpgradeViaFactory. Затем вызывается UpgradeProject_CheckOnly для проверки необходимости обновления файлов глобального проекта и для определения поддерживаемых стратегий обновления. Затем вызывается мастер обновления .

После того как пользователь завершит работу мастера, UpgradeProject вызывается на каждой фабрике проектов для выполнения фактического обновления. Для упрощения резервного копирования методы IVsProjectUpgradeViaFactory предоставляют SVsUpgradeLogger службе сведения о процессе обновления. Эту службу нельзя кэшировать.

После обновления всех соответствующих глобальных файлов каждая проектная фабрика может решить создать экземпляр проекта. Проектная реализация должна поддерживать IVsProjectUpgrade. Затем вызывается метод UpgradeProject, чтобы обновить все соответствующие элементы проекта.

Замечание

Метод UpgradeProject не предоставляет службу SVsUpgradeLogger. Эта служба может быть получена путем вызова QueryService.

Лучшие практики

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

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

Дополнительные сведения о резервном копировании и обновлении проектов см. в комментариях для IVsProjectUpgrade в vsshell2.idl.

Обновление пользовательских проектов

При изменении сведений, сохраненных в файле проекта между различными версиями продукта Visual Studio, необходимо поддерживать обновление файла проекта с старого до новой версии. Чтобы поддерживать обновление, позволяющее участвовать в мастере преобразования Visual Studio, реализуйте интерфейс IVsProjectUpgradeViaFactory. Этот интерфейс содержит единственный механизм, доступный для улучшения копирования. Обновление проекта происходит в процессе открытия решения. Интерфейс IVsProjectUpgradeViaFactory реализуется фабрикой проектов или по крайней мере должен быть доступен из фабрики проектов.

Старый механизм, использующий IVsProjectUpgrade интерфейс, по-прежнему поддерживается, но концептуально обновляет систему проекта в рамках открытого проекта. Поэтому IVsProjectUpgrade интерфейс вызывается средой Visual Studio, даже если IVsProjectUpgradeViaFactory интерфейс вызывается или реализуется. Этот подход позволяет использовать IVsProjectUpgradeViaFactory для копирования и проецирования лишь части обновления, а остальную часть работы делегировать на выполнение на месте (возможно, в новом расположении) через интерфейс IVsProjectUpgrade.

Пример реализации IVsProjectUpgradeсм. в разделе "Примеры VSSDK".

Следующие сценарии возникают при обновлении проекта:

  • Если файл имеет более новый формат, чем проект может поддерживать, он должен вернуть ошибку, указывая на это. В этом случае предполагается, что более старая версия продукта содержит код для проверки версии.

  • PUVFF_SXSBACKUP Если флаг указан в методе UpgradeProject, обновление будет выполнено как локальное обновление перед открытием проекта.

  • PUVFF_COPYBACKUP Если флаг указан в методе UpgradeProject, обновление реализуется как копировальное обновление.

  • Если в вызове UPF_SILENTMIGRATE указан флаг UpgradeProject, то после открытия проекта пользователю будет предложено выполнить обновление файла проекта на месте. Например, среда предложит пользователю обновиться, когда пользователь открывает старую версию решения.

  • UPF_SILENTMIGRATE Если флаг не указан в вызовеUpgradeProject, необходимо предложить пользователю обновить файл проекта.

    Ниже приведен пример сообщения запроса на обновление:

    Проект%1создан с более старой версией Visual Studio. Если открыть его с помощью этой версии Visual Studio, возможно, вы не сможете открыть его с более ранними версиями Visual Studio. Вы хотите продолжить и открыть этот проект?

Для реализации IVsProjectUpgradeViaFactory

  1. Реализуйте метод интерфейса IVsProjectUpgradeViaFactory, в частности метод UpgradeProject, в реализации фабрики проектов, или сделайте так, чтобы реализации могли вызываться из вашей реализации фабрики проектов.

  2. Если вы хотите выполнить обновление на месте в рамках открытия решения, укажите флаг PUVFF_SXSBACKUP в качестве VSPUVF_FLAGS параметра в реализации UpgradeProject .

  3. Если вы хотите выполнить обновление на месте в рамках открытия решения, укажите флаг PUVFF_COPYBACKUP в качестве VSPUVF_FLAGS параметра в реализации UpgradeProject .

  4. Для шагов 2 и 3 фактические шаги обновления файлов, используя IVsQueryEditQuerySave2, можно реализовать, как описано в разделе "Реализация IVsProjectUpgade" ниже, или делегировать фактическое обновление файла IVsProjectUpgrade.

  5. Используйте методы IVsUpgradeLogger для публикации сообщений, связанных с обновлением, для пользователя с помощью мастера миграции Visual Studio.

  6. IVsFileUpgrade интерфейс используется для реализации любого типа обновления файлов, которое должно произойти в процессе обновления проекта. Этот интерфейс не вызывается из IVsProjectUpgradeViaFactory, но предоставляется в качестве механизма для обновления файлов, которые являются частью системы проекта, хотя основная система проекта может быть не напрямую осведомлена о них. Например, эта ситуация может возникнуть, если связанные с компилятором файлы и свойства не обрабатываются той же командой разработки, которая обрабатывает остальную часть системы проекта.

Реализация IVsProjectUpgrade

Если система проектов реализует только IVsProjectUpgrade, она не может использовать Мастер преобразования Visual Studio. Тем не менее, даже если вы реализуете IVsProjectUpgradeViaFactory интерфейс, вы все равно можете делегировать обновление файла реализации на IVsProjectUpgrade.

Для реализации IVsProjectUpgrade

  1. Когда пользователь пытается открыть проект, UpgradeProject метод вызывается средой после открытия проекта и перед выполнением любого другого действия пользователя в проекте. Если пользователю уже было предложено обновить решение, UPF_SILENTMIGRATE флаг передается в параметре grfUpgradeFlags . Если пользователь открывает проект напрямую, например, с помощью команды «Добавить существующий проект», то флаг UPF_SILENTMIGRATE не передается, и проект должен предложить пользователю обновление.

  2. В ответ на UpgradeProject вызов проект должен оценить, обновляется ли файл проекта. Если проекту не нужно обновить тип проекта до новой версии, он может просто вернуть S_OK флаг.

  3. Если проекту необходимо обновить тип проекта до новой версии, необходимо определить, может ли файл проекта измениться путем вызова QueryEditFiles метода и передачи значения tagVSQueryEditFlags параметра rgfQueryEdit . Затем проект должен выполнить следующие действия:

    • Если значение VSQueryEditResult, возвращаемое в параметре pfEditCanceled, равно QER_EditOK, то обновление может продолжиться, так как файл проекта можно записать.

    • VSQueryEditResult Если значение, возвращаемое в параметре pfEditCanceled, равно QER_EditNotOK и значение VSQueryEditResult имеет установленный бит QER_ReadOnlyNotUnderScc, то UpgradeProject должен вернуть код ошибки, так как пользователи должны самостоятельно устранить проблемы с разрешениями. Затем проект должен выполнить следующие действия:

      Сообщите об ошибке пользователю, вызвав ReportErrorInfo, и верните код ошибки VS_E_PROJECTMIGRATIONFAILED к IVsProjectUpgrade.

    • Если значение VSQueryEditResult равно QER_EditNotOK, и бит QER_ReadOnlyUnderScc установлен в значении VSQueryEditResultFlags, файл проекта должен быть извлечен путем вызова QueryEditFiles (QEF_ForceEdit_NoPrompting, QEF_DisallowInMemoryEdits, ...).

  4. QueryEditFiles Если вызов файла проекта приводит к извлечению файла и последней версии, то проект выгрузится и перезагрузится. Метод UpgradeProject вызывается еще раз, когда создается другой экземпляр проекта. Во второй раз файл проекта можно записать на диск; рекомендуется сохранить копию файла проекта в предыдущем формате с расширением .OLD, внести необходимые изменения для обновления и сохранить файл проекта в новом формате. Опять же, если любая часть процесса обновления завершается ошибкой, метод должен указывать на сбой, возвращая VS_E_PROJECTMIGRATIONFAILED. Это приводит к выгрузке проекта в обозревателе решений.

    Важно понимать полный процесс, происходящий в среде, в случае, когда вызов QueryEditFiles метода (указание значения ReportOnly) возвращает QER_EditNotOK и QER_ReadOnlyUnderScc флаги.

  5. Пользователь пытается открыть файл проекта.

  6. Среда вызывает вашу реализацию CanCreateProject.

  7. Если CanCreateProject возвращает true, среда вызывает вашу реализацию CanCreateProject.

  8. Среда вызывает Load реализацию, чтобы открыть файл и инициализировать объект проекта, например Project1.

  9. Среда вызывает вашу реализацию IVsProjectUpgrade::UpgradeProject, чтобы определить, требуется ли обновить файл проекта.

  10. Вы вызываете QueryEditFiles и передаете значение QEF_ReportOnly для параметра rgfQueryEdit.

  11. Среда возвращает QER_EditNotOK для VSQueryEditResult, и бит QER_ReadOnlyUnderScc устанавливается в VSQueryEditResultFlags.

  12. Ваша реализация IVsProjectUpgrade вызывает IVsQueryEditQuerySave::QueryEditFiles (QEF_ForceEdit_NoPrompting, QEF_DisallowInMemoryEdits).

Этот вызов может привести к извлечению новой копии файла проекта и последней версии, а также необходимости перезагрузить файл проекта. На этом этапе происходит одно из двух вещей:

  • Если вы обрабатываете перезагрузку собственного проекта, среда вызывает ReloadItem реализацию (VSITEMID_ROOT). При получении этого вызова перезагрузите первый экземпляр проекта (Project1) и продолжите обновление файла проекта. Среда знает, что вы обрабатываете перезагрузку собственного проекта, если вернете true для GetProperty (VSHPROPID_HandlesOwnReload).

  • Если вы не обрабатываете перезагрузку собственного проекта, то возвращаете false для GetProperty (VSHPROPID_HandlesOwnReload). В этом случае перед QueryEditFiles возвратом (QEF_ForceEdit_NoPrompting, QEF_DisallowInMemoryEdits), среда создаёт новый экземпляр вашего проекта, например Project2, как указано ниже.

    1. Среда вызывает Close на вашем первом объекте проекта, Project1, тем самым помещая этот объект в неактивное состояние.

    2. Среда вызывает реализацию IVsProjectFactory::CreateProject для создания второго экземпляра проекта Project2.

    3. Среда вызывает реализацию IPersistFileFormat::Load для того, чтобы открыть файл и инициализировать второй объект проекта Project2.

    4. Среда вызывает IVsProjectUpgrade::UpgradeProject второй раз, чтобы определить, следует ли обновить объект проекта. Однако этот вызов выполняется во втором новом экземпляре проекта Project2. Это проект, открытый в решении.

      Замечание

      Если ваш первый проект, Project1, находится в неактивном состоянии, то вы должны вернуть S_OK из первого вызова вашей реализации UpgradeProject.

    5. Вы вызываете QueryEditFiles и передаете значение QEF_ReportOnly для параметра rgfQueryEdit.

    6. Среда возвращает QER_EditOK, и обновление продолжается, поскольку файл проекта можно записать.

Если вам не удается обновить, возвратите VS_E_PROJECTMIGRATIONFAILED из IVsProjectUpgrade::UpgradeProject. Если обновление не требуется или вы решили не обновлять, рассматривайте вызов IVsProjectUpgrade::UpgradeProject как отсутствие операции. При возврате VS_E_PROJECTMIGRATIONFAILED узел заполнителя добавляется в решение для вашего проекта.

Обновление элементов проекта

При добавлении или управлении элементами в системах проектов, которые не реализованы, может потребоваться принять участие в процессе обновления проекта. Crystal Reports — это пример элемента, который можно добавить в систему проекта.

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

Получение уведомления об обновлении проекта

  1. Задайте флаг SolutionOrProjectUpgrading (определенный в vsshell80.idl) в реализации элемента вашего проекта. Это приводит к автоматической загрузке элемента проекта VSPackage, когда оболочка Visual Studio определяет, что система проекта находится в процессе обновления.

  2. Дайте совет интерфейсу через метод AdviseSolutionEvents.

  3. Интерфейс IVsSolutionEventsProjectUpgrade запускается после завершения выполнения операций обновления системы проекта и создания нового обновленного проекта. В зависимости от сценария интерфейс IVsSolutionEventsProjectUpgrade вызывается после метода OnAfterOpenSolution, метода OnAfterOpenProject, или метода OnAfterLoadProject.

Обновление файлов элементов проекта

  1. Необходимо тщательно управлять процессом резервного копирования файлов в реализации элемента проекта. Это в особенности актуально для резервного копирования бок о бок, где параметр fUpgradeFlag метода UpgradeProject установлен на PUVFF_SXSBACKUP, и файлы, которые были резервированы, размещаются рядом с файлами, обозначенными как ".old". Резервные копии файлов, которые старше системного времени обновления проекта, можно считать устаревшими. Кроме того, они могут быть перезаписаны, если не предпринять конкретные действия, чтобы предотвратить это.

  2. В момент, когда элемент проекта получает уведомление о его обновлении, мастер преобразования Visual Studio всё ещё отображается. Поэтому следует использовать методы интерфейса IVsUpgradeLogger для предоставления сообщений об обновлении в UI мастера.