Перенос проекта среды выполнения Windows 8.x в проект UWP

У вас есть два варианта разработки процесса переноса. Первый — изменить копии существующих файлов проекта, в том числе манифест пакета приложения (для этого варианта см. сведения об обновлении файлов проекта в разделе Перенос приложений на универсальную платформу Windows (UWP)). Второй – создать новый проект Windows 10 в Visual Studio и скопировать файлы в него. В первом подпункте этого раздела описан второй вариант, но в остальной части раздела можно найти дополнительную информацию, применимую к обоим вариантам. Можно также сохранить новый проект Windows 10 в решении с существующими проектами и совместно использовать файлы исходного кода с помощью общего проекта. Или можно сохранить новый проект в собственном решении и совместно использовать файлы кода с помощью функции связанных файлов в Visual Studio.

Создайте проект и скопируйте в него файлы.

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

  1. Запустите Microsoft Visual Studio 2015 и создайте новый проект "Пустое приложение (Windows Universal)". Дополнительные сведения см. в статье Начало работы с приложением среда выполнения Windows 8.x с помощью шаблонов (C#, C++, Visual Basic). Новый проект выполняет сборку пакета приложения (APPX-файла), который будет работать на всех семействах устройств.
  2. В проекте универсального приложения для версии 8.1 определите все файлы исходного кода и файлы визуального актива, которые вы хотите использовать. С помощью проводника скопируйте модели, модели представления, визуальные активы, словари ресурсов, структуру папок и все остальное, что вы хотите повторно использовать, в новый проект. Скопируйте или создайте вложенные папки на диске по мере необходимости.
  3. Скопируйте также представления (например, файлы MainPage.xaml и MainPage.xaml.cs) в новый проекта. Напоминаем еще раз: создавайте новые вложенные папки по мере необходимости и удаляйте существующие представления из проекта. Но перед тем, как переписывать или удалять представление, созданное Visual Studio, сохраните его копию, так как она может оказаться полезной позднее. Первая фаза переноса универсального приложения для версии 8.1 сфокусирована на хорошем отображении и работе приложения на одном семействе устройств. Позже вы уделите внимание адаптации представлений ко всем форм-факторам и при необходимости добавите адаптивный код, чтобы использовать все возможности определенного семейства устройств.
  4. В Обозревателе решенийубедитесь, что функция Показать все файлы включена. Выберите скопированные файлы, щелкните их правой кнопкой мыши и выберите Включить в проект. Это автоматически включит содержащиеся в них папки. Затем можно выключить параметр Показать все файлы , если требуется. Если вы предпочитаете альтернативный процесс, используйте команду Добавить существующий элемент после создания всех необходимых вложенных папок в Обозревателе решений Visual Studio. Дважды убедитесь, что Действие при сборке ваших визуальных активов установлено на Содержимое и Копировать в выходной каталог установлено на Не копировать.
  5. Возможно, на этом этапе будут возникать некоторые ошибки сборки. Но если вы знаете, что требуется изменить, вы можете использовать команду Visual Studio Найти и заменить для внесения массовых изменений в исходный код. В редакторе императивного кода Visual Studio используйте команды Разрешить и Упорядочение Using в контекстном меню для внесения более нацеленных изменений.

Максимальное использование существующей разметки и кода

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

  • Для файлов, которые используются на всех семействах устройств, не требуется никакой дополнительной обработки. Эти файлы будут использоваться приложением на всех семействах устройств. Сюда входят файлы разметки XAML, файлы императивного исходного кода и файлы ресурсов.
  • Ваше приложение может определять семейство устройств, на котором оно работает, и переходить в представление, созданное специально для такого семейства. Дополнительные сведения см. в разделе Определение платформы, на которой работает приложение.
  • Если нет альтернативы, может оказаться полезным похожий метод — изменить имя файла разметки или файла ResourceDictionary (или папки, содержащей файл) на специальное имя, чтобы он автоматически загружался во время выполнения только при запуске приложения на определенном семействе устройств. Этот метод проиллюстрирован в примере Bookstore1.
  • Вы сможете удалить многие директивы условной компиляции в исходном коде универсального приложения версии 8.1, если вам необходима поддержка только Windows 10. См. подраздел Условная компиляция и адаптивный код в этом разделе.
  • Чтобы использовать функции, которые доступны не на всех семействах устройств (например, принтеры, сканеры или кнопку камеры), можно написать адаптивный код. См. третий пример в подразделе Условная компиляция и адаптивный код в этом разделе.
  • Для поддержки Windows 8.1, Windows Phone 8.1 и Windows 10 вы можете сохранить три проекта в одном решении и использовать код с помощью общего проекта. Кроме того, можно также совместно использовать файлы исходного кода в разных проектах. Порядок действий: в Visual Studio, щелкните правой кнопкой мыши проект в Обозревателе решений, выберите Добавить существующий элемент, выберите файлы для совместного использования и затем щелкните Добавить как связь. Храните файлы исходного кода в общей папке в файловой системе, в которой привязанные к ним проекты могут их видеть. И не забывайте добавлять их в систему управления версиями.
  • Сведения о повторном использовании на двоичном уровне, а не на уровне исходного кода, см. в статье Создание компонентов среда выполнения Windows в C# и Visual Basic. Существуют также переносимые библиотеки классов, которые поддерживают подмножество API .NET, доступные в .NET Framework для Windows 8.1, Windows Phone 8.1 и Windows 10 (.NET Core) и в полной платформе .NET Framework. Сборки переносимой библиотеки классов совместимы на уровне двоичного кода со всеми этими платформами. Используйте Visual Studio для создания проекта, который использует переносимую библиотеку классов. См. раздел Кроссплатформенная разработка с помощью переносимой библиотеки классов.

Пакеты SDK расширения

Большая часть API-интерфейсов среды выполнения Windows, которые вызывает ваше универсальное приложение для версии 8.1, уже реализованы в наборе API-интерфейсов, известном как семейство универсальных устройств. Но некоторые из них реализованы в пакетах SDK расширения, и Visual Studio распознает только API, реализованные целевым семейством устройств вашего приложения или любыми пакетами SDK расширений, на которые вы ссылаетесь.

Если возникают ошибки компиляции, связанные с пространствами имен, типами или членами, которые не удается найти, это может оказаться причиной. Откройте раздел API в справочной документации по API и перейдите к разделу "Требования". Так вы определите целевое семейство устройств. Если это не ваше целевое семейство устройств, вам потребуется ссылка на SDK расширения для этого семейства устройств, чтобы сделать API доступным в проекте.

Щелкните ProjectAdd ReferenceWindows UniversalExtensions (Добавить >эталонные>универсальные> расширения Windows) и выберите соответствующий пакет SDK расширения. Например, если нужные API-интерфейсы доступны только для семейства мобильных устройств и они появились в версии 10.0.x.y, выберите Windows Mobile Extensions для UWP.

После этого следующая ссылка будет добавлена в файл проекта:

<ItemGroup>
    <SDKReference Include="WindowsMobile, Version=10.0.x.y">
        <Name>Windows Mobile Extensions for the UWP</Name>
    </SDKReference>
</ItemGroup>

Имя и номер версии соответствуют папкам в месте установки SDK. Например, данные выше соответствуют этому имени папки:

\Program Files (x86)\Windows Kits\10\Extension SDKs\WindowsMobile\10.0.x.y

Если ваше приложение не предназначено для семейства устройств, которое реализует API, вам необходимо использовать класс ApiInformation, чтобы проверить наличие API, прежде чем вызывать его (это называется адаптивным кодом). Это условие оценивается при каждом запуске приложения, но оно будет истинным только на устройствах, где этот API присутствует и, следовательно, доступен. Используйте пакеты SDK расширения и адаптивный код только после проверки существования универсального API. Некоторые примеры представлены в разделе ниже.

См. также раздел Манифест пакета приложения.

Условная компиляция и адаптивный код

Если вы используете условную компиляцию (с директивами препроцессора C#), чтобы файлы кода работали в Windows 8.1 и Windows Phone 8.1, теперь вы можете проверить условную компиляцию благодаря конвергенции в Windows 10. Конвергенция означает, что в приложении Windows 10 некоторые условия можно удалить. А другие условия изменить на проверки во время выполнения, как показано в примерах ниже.

Примечание Если вы хотите поддерживать Windows 8.1, Windows Phone 8.1 и Windows 10 в одном файле кода, это также можно сделать. Если вы посмотрите на страницы свойств проекта Windows 10, вы увидите, что проект определяет WINDOWS_UAP в качестве символа условной компиляции. Таким образом, вы можете использовать его в сочетании с WINDOWS_APP и WINDOWS_PHONE_APP. В этих примерах показан более простой случай удаления условной компиляции из универсального приложения для версии 8.1 и замены эквивалентного кода для приложения Windows 10.

В первом примере показан шаблон использования API PickSingleFileAsync (относится только к Windows 8.1) и API PickSingleFileAndContinue (относится только к Windows Phone 8.1).

#if WINDOWS_APP
    // Use Windows.Storage.Pickers.FileOpenPicker.PickSingleFileAsync
#else
    // Use Windows.Storage.Pickers.FileOpenPicker.PickSingleFileAndContinue
#endif // WINDOWS_APP

В Windows 10 API-интерфейс PickSingleFileAsync объединен, поэтому код упрощается следующим образом:

    // Use Windows.Storage.Pickers.FileOpenPicker.PickSingleFileAsync

В этом примере мы обрабатываем аппаратную кнопку "Назад", но только на Windows Phone.

#if WINDOWS_PHONE_APP
        Windows.Phone.UI.Input.HardwareButtons.BackPressed += this.HardwareButtons_BackPressed;
#endif // WINDOWS_PHONE_APP

...

#if WINDOWS_PHONE_APP
    void HardwareButtons_BackPressed(object sender, Windows.Phone.UI.Input.BackPressedEventArgs e)
    {
        // Handle the event.
    }
#endif // WINDOWS_PHONE_APP

В Windows 10 событие кнопки "Назад" — это универсальная концепция. Кнопки перехода назад, реализованные аппаратно или программно, вызывают событие BackRequested, поэтому обрабатывать нужно только одно событие для всех кнопок.

    Windows.UI.Core.SystemNavigationManager.GetForCurrentView().BackRequested +=
        this.ViewModelLocator_BackRequested;

...

private void ViewModelLocator_BackRequested(object sender, Windows.UI.Core.BackRequestedEventArgs e)
{
    // Handle the event.
}

Последний пример похож на предыдущий. Здесь мы обрабатываем аппаратную кнопку камеры, но опять же только в коде, скомпилированном в пакет приложения для Windows Phone.

#if WINDOWS_PHONE_APP
    Windows.Phone.UI.Input.HardwareButtons.CameraPressed += this.HardwareButtons_CameraPressed;
#endif // WINDOWS_PHONE_APP

...

#if WINDOWS_PHONE_APP
void HardwareButtons_CameraPressed(object sender, Windows.Phone.UI.Input.CameraEventArgs e)
{
    // Handle the event.
}
#endif // WINDOWS_PHONE_APP

В Windows 10 аппаратная кнопка камеры — это концепция, связанная с семейством мобильных устройств. Поскольку один пакет приложения будет работать на всех устройствах, мы изменим условие времени компиляции на условие времени выполнения, что называется адаптивным кодом. Для этого мы используем класс ApiInformation, чтобы запрашивать во время выполнения сведения о наличии класса HardwareButtons. Класс HardwareButtons определен в мобильном SDK расширения, поэтому нам потребуется добавить ссылку на этот SDK в наш проект для компиляции кода. Обратите внимание, что обработчик будет выполнен только на устройстве, на котором реализованы типы, определенные в мобильном SDK расширения. Это семейство мобильных устройств. Этот код эквивалентен коду универсального приложения для версии 8.1 тем, что используются только существующие функции, хотя это реализовано по-другому.

    // Note: Cache the value instead of querying it more than once.
    bool isHardwareButtonsAPIPresent = Windows.Foundation.Metadata.ApiInformation.IsTypePresent
        ("Windows.Phone.UI.Input.HardwareButtons");

    if (isHardwareButtonsAPIPresent)
    {
        Windows.Phone.UI.Input.HardwareButtons.CameraPressed +=
            this.HardwareButtons_CameraPressed;
    }

    ...

private void HardwareButtons_CameraPressed(object sender, Windows.Phone.UI.Input.CameraEventArgs e)
{
    // Handle the event.
}

См. также раздел Определение платформы, на которой работает приложение.

Манифест пакета приложения

В разделе Изменения в Windows 10 перечислены изменения, которые были внесены в справочные материалы по схеме манифеста пакета для Windows 10, в том числе элементы, которые были добавлены, удалены и изменены. Справочную информацию по всем элементам, атрибутам и типам в схеме см. в разделе Иерархия элементов. Если вы переносите приложение Windows Phone Store или ваше приложение является обновлением приложения из магазина Windows Phone, убедитесь, что элемент mp:PhoneIdentity соответствует тому, что находится в манифесте предыдущего приложения (используйте те же идентификаторы GUID, которые были назначены приложению Магазином). Это гарантирует, что пользователи приложения, которые обновляются до Windows 10 или Windows 11, получат новое приложение в виде обновления, а не дубликата. Дополнительные сведения см. в справочном разделе mp:PhoneIdentity .

Параметры в проекте (включая любые ссылки на пакеты SDK расширения) определяют контактную зону API, которую может вызвать ваше приложение. Но манифест пакета приложения — это инструмент, который определяет фактический набор устройств, на которые клиенты смогут устанавливать приложение из Магазина. Подробнее см. в примерах в разделе TargetDeviceFamily.

Манифест пакета приложения можно редактировать, чтобы устанавливать различные объявления, возможности и другие параметры, необходимые для некоторых функций. Для его изменения можно использовать редактор манифеста пакета приложения в Visual Studio. Если Solution Explorer (Обозреватель решений) не отображается, выберите его в меню View (Вид). Дважды щелкните Package.appxmanifest. Откроется окно редактора манифестов. Выберите соответствующую вкладку, чтобы внести изменения, а затем сохраните.

Следующий раздел называется Устранение неполадок.