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


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

Изменения в модели проекта из одной версии 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".

При обновлении проектов возникают описанные ниже ситуации.

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

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

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

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

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

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

    "Проект "%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 и в значении VSQueryEditResultFlags задан бит QER_ReadOnlyUnderScc, то файл проекта следует получить для изменения, вызвав метод 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, а в VSQueryEditResultFlags устанавливается бит QER_ReadOnlyUnderScc.

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

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

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

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

    1. Среда вызывает метод Close для первого объекта проекта (Project1), переводя его таким образом в неактивное состояние.

    2. Среда вызывает вашу реализацию метода IVsProjectFactory::CreateProject , чтобы создать второй экземпляр проекта (Project2).

    3. Среда вызывает вашу реализацию метода IPersistFileFormat::Load для открытия файла и инициализации второго объекта проекта (Project2).

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

      Примечание.

      В случае если первый проект (Project1) переведен в неактивное состояние, в результате первого вызова реализации UpgradeProject должно возвращаться значение S_OK.

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

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

В случае сбоя обновления метод IVsProjectUpgrade::UpgradeProject должен возвращать значение VS_E_PROJECTMIGRATIONFAILED. Если обновление не требуется или вы решили не производить его, вызов IVsProjectUpgrade::UpgradeProject следует рассматривать как холостой. Если возвращается код ошибки VS_E_PROJECTMIGRATIONFAILED, в решение проекта добавляется узел-заполнитель.

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

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

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

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

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

  2. IVsSolutionEventsProjectUpgrade Советуйте интерфейсу с помощью AdviseSolutionEvents метода.

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

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

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

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