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


Перенос проекта среды выполнения 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). Дополнительные сведения см. в статье Запуск приложения на платформе Windows Runtime 8.x с помощью шаблонов (C#, C++, Visual Basic). Новый проект создает пакет приложения (appx-файл), который будет выполняться во всех семействах устройств.
  2. В проекте универсального приложения 8.1 определите все файлы исходного кода и файлы визуальных активов, которые требуется повторно использовать. Используя Проводник, скопируйте модели данных, модели представлений, визуальные ресурсы, словари ресурсов, структуру папок и другие элементы, которые вы хотите повторно использовать, в новый проект. При необходимости скопируйте или создайте вложенные папки на диске.
  3. Скопируйте представления (например, MainPage.xaml и MainPage.xaml.cs) в новый проект. При необходимости создайте новые вложенные папки и удалите существующие представления из проекта. Но перед перезаписью или удалением представления, созданного Visual Studio, сохраните копию, так как она может оказаться полезной для ссылки на нее позже. Первый этап портирования универсального приложения 8.1 фокусируется на том, чтобы он выглядел хорошо и эффективно работал на подходящей группе устройств. Позже вы обратите внимание на то, чтобы представления хорошо адаптировались ко всем форм-факторам, при необходимости добавляя адаптивный код, чтобы максимально использовать возможности определенного семейства устройств.
  4. В обозревателе решенийубедитесь, что Показать все файлы включено. Выберите скопированные файлы, щелкните их правой кнопкой мыши и щелкните Включить в проект. Это будет автоматически включать их содержащиеся папки. После этого можно отключить показать все файлы, если вы хотите. Альтернативный рабочий процесс, если вы предпочитаете, заключается в использовании команды добавить существующий элемент, предварительно создав все необходимые вложенные папки в Visual Studio Solution Explorer . Дважды убедитесь, что для ваших визуальных ресурсов в параметре Действие сборки установлено значение Содержимое и в параметре Копировать в выходной каталог выбрано значение Не копировать.
  5. Скорее всего, на этом этапе вы увидите некоторые ошибки сборки. Но если вы знаете, что нужно изменить, вы можете использовать команду Find and Replace в 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 и перейдите в раздел "Требования", чтобы определить семейство устройств, для которых предназначена данная реализация. Если это не ваше семейство целевых устройств, то чтобы сделать API доступным для проекта, вам потребуется ссылка на пакет SDK расширений для этого семейства устройств.

Щелкните Project>Add Reference>Windows Universal>Extensions и выберите соответствующий пакет SDK расширений. Например, если API, которые вы хотите вызвать, доступны только в семействе мобильных устройств, и они были представлены в версии 10.0.x.y, выберите Дополнения Windows Mobile для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 или приложение является обновлением приложения из Магазина Windows Phone, убедитесь, что элемент mp:PhoneIdentity соответствует тому, что находится в манифесте приложения предыдущего приложения (используйте те же идентификаторы GUID, которые были назначены приложению Магазином). Это гарантирует, что пользователи приложения, которые обновляются до Windows 10 или Windows 11, получат новое приложение в качестве обновления, а не дубликата. Дополнительные сведения см. в справочной статье mp:PhoneIdentity .

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

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

Следующая тема — устранение неполадок.