Подготовка к упаковке классического приложения

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

  • Для приложения .NET требуется версия .NET Framework более ранняя, чем 4.6.2. При упаковке приложения .NET рекомендуется, чтобы для него использовалась платформа .NET Framework 4.6.2 или более поздней версии. Возможность установки и запуска упакованных классических приложений впервые появилась в Windows 10 версии 1607 (также именуемой юбилейным обновлением). Эта версия ОС включает в себя .NET Framework 4.6.2 по умолчанию. Более поздние версии ОС включают в себя более поздние версии .NET Framework. Полный список версий .NET, которые входят в состав более поздних версий Windows 10, см. в этой статье.

    .NET Framework более ранних версий, чем 4.6.2, работает с упакованными классическими приложениями в большинстве случаев. Тем не менее, если вы используете более раннюю версию, чем 4.6.2, следует полностью протестировать упакованное классическое приложение перед его распространением среди пользователей.

    • 4.0–4.6.1. Ожидается, что приложения, предназначенные для этих версий .NET Framework, будут работать без проблем на платформе версии 4.6.2 или более поздних версий. Поэтому такие приложения должны устанавливаться и работать без изменений в Windows 10 версии 1607 или более поздних с версией .NET Framework, которая предусмотрена в операционной системе.

    • 2.0 и 3.5. Согласно результатам нашего тестирования упакованные классические приложения, разработанные для этих версий .NET Framework, обычно работают, но в некоторых сценариях могут возникать проблемы с производительностью. Чтобы эти упакованные приложения могли устанавливаться и запускаться, на целевом компьютере должен быть установлен компонент .NET Framework 3.5 (он также включает в себя .NET Framework 2.0 и 3.0). Следует также тщательно протестировать эти приложения после их упаковки.

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

  • Для приложения требуется работающий в режиме ядра драйвер или служба Windows. Пакеты MSIX не поддерживают работающий в режиме ядра драйвер или службу Windows, которая должна работать с использованием системной учетной записи. Вместо службы Windows используйте фоновую задачу.

  • Модули вашего приложения загружаются во внутрипроцессном режиме в процессы, которые отсутствуют в пакете приложения для Windows. Это запрещено и означает, что внутрипроцессные расширения, такие как расширения оболочки не поддерживаются. Но если у вас есть два приложения в одинаковом пакете, вы можете настроить межпроцессное взаимодействие между ними.

  • Необходимо обеспечить, чтобы приложение установило все расширения там, где установлено само приложение. Windows позволяет пользователям и ИТ-менеджерам изменять расположение установки по умолчанию для пакетов. Для этого выберите следующее: Параметры->Система ->Хранилище ->Дополнительные параметры хранилища ->Change where new content is saved to (Изменение места сохранения нового содержимого) ->New Apps will save to (Новые приложения будут сохраняться в). Если вы устанавливаете расширение с помощью приложения, убедитесь, что расширение не предусматривает дополнительные ограничения в отношении папки установки. Например, некоторые расширения могут отключать установку на несистемные диски. Если в таком случае изменить расположение по умолчанию, это повлечет возникновение ошибки 0x80073D01 (ERROR_DEPLOYMENT_BLOCKED_BY_POLICY).

  • Ваше приложение использует настраиваемый идентификатор модели пользователя приложения (AUMID) . Если ваш процесс вызывает команду SetCurrentProcessExplicitAppUserModelID, чтобы задать собственный AUMID, то можно использовать только AUMID, созданный для процесса средой модели приложения или пакетом приложения для Windows. Вы не можете определять пользовательские AUMID.

  • Ваше приложение изменяет куст реестра HKEY_LOCAL_MACHINE (HKLM) . Любая попытка приложения создать раздел HKLM или открыть такой раздел для изменения приведет к сбою в виде отказа в доступе. Не забывайте, что у вашего приложения есть собственное закрытое виртуализированное представление реестра, поэтому в такой ситуации понятие куста реестра на уровне пользователя или компьютера (чем является HKLM) неприменимо. Потребуется найти другой способ достичь того, чего требовалось при использовании HKLM, например запись в HKEY_CURRENT_USER (HKCU).

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

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

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

    Используйте другие средства межпроцессного обмена данными. Подробнее: Хранение и извлечение параметров и прочих данных приложения.

  • Приложение выполняет запись в каталог установки приложения. Например, ваше приложение выполняет запись в файл журнала, который вы поместили в тот же каталог, что и EXE-файл. Эта операция не поддерживается, поэтому потребуется найти другое расположение, например, локальное хранилище данных приложения.

  • Приложение использует текущий рабочий каталог. В среде выполнения ваше упакованное классическое приложение не получит тот же рабочий каталог, который ранее указан для вашего ярлыка LNK на рабочем столе. Необходимо изменить CWD в среде выполнения, если у вашего приложения должен быть правильный каталог, чтобы оно работало должным образом.

    Примечание

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

  • Для установки приложения требуется участие пользователя. Ваш установщик приложения должен поддерживать возможность работы в автоматическом режиме, а также должен устанавливать все свои дополнительные компоненты, которых нет по умолчанию в чистом образе ОС.

  • Приложение предоставляет COM-объекты. Процессы и расширения из пакета могут регистрировать и использовать COM- и OLE-серверы, как внутри, так и вне процессов. В Creators Update добавлена поддержка технологии упаковки COM-объектов, позволяющая вне процессов регистрировать COM- и OLE-серверы, которые теперь видны за пределами пакета. Дополнительные сведения см. в записи блога COM Server and OLE Document support for Desktop Bridge (Поддержка COM-сервера и документа OLE для моста для классических приложений).

    Технология упакованных COM-объектов работает с существующими API COM, но не будет работать для расширений приложения, которые напрямую считывают реестр, так как расположение для упакованных COM-объектов находится в частном расположении.

  • Приложение разрешает другим процессам использовать сборки из глобального кэша сборок (GAC) . Приложение не может предоставлять сборки GAC процессам из исполняемых файлов, которые являются внешними по отношению к пакету приложения Windows. Процессы из пакета могут регистрировать и использовать сборки GAC обычным образом, но они не будут видны извне. Это означает, что сценарии межпрограммного взаимодействия (например, OLE) не будут работать при их вызове внешними процессами.

  • Приложение связывается с библиотеками среды выполнения C (CRT) неподдерживаемым способом. Библиотека времени выполнения C/C++ Майкрософт предоставляет процедуры для программирования в среде операционной системы Microsoft Windows. Эти процедуры автоматизируют выполнение многих распространенных задач программирования, которые не предоставляются языками C и C++. Если ваше приложение использует библиотеку среды выполнения C или C++, необходимо убедиться, что связь с ней устанавливается поддерживаемым способом.

    Visual Studio 2017 поддерживает как динамическое связывание, чтобы в коде можно было использовать общие файлы DLL, так и статическое связывание для связывания библиотеки с текущей версией CRT прямо в коде. Мы рекомендуем по возможности использовать в приложениях динамическое связывание Visual Studio 2017.

    Поддержка различных типов связывания зависит от версии Visual Studio. Подробности см. в следующей таблице:

    Версия Visual StudioДинамическое связываниеСтатическое связывание
    2005 (VC 8)Не поддерживаетсяПоддерживается
    2008 (VC 9)Не поддерживаетсяПоддерживается
    2010 (VC 10)ПоддерживаетсяПоддерживается
    2012 (VC 11)ПоддерживаетсяНе поддерживается
    2013 (VC 12)ПоддерживаетсяНе поддерживается
    2015 и 2017 (VC 14)ПоддерживаетсяПоддерживается

    Примечание. Во всех случаях связывание необходимо выполнять с общедоступной библиотекой CRT самой последней версии.

  • Приложение устанавливает и загружает сборки из параллельной папки side-by-side (SxS) Windows. Например, в вашем приложении используются библиотеки среды выполнения C VC8 или VC9 и они динамически связываются из папки SxS Windows, т. е. в коде используются общие файлы DLL из общей папки. Такой способ связывания не поддерживается. Необходимо подключать их статически, то есть связать с распространяемыми файлами библиотеки непосредственно в самом коде.

  • Ваше приложение использует зависимость в папке System32/SysWOW64. Чтобы эти файлы DLL начали работать, необходимо включить их в часть вашего пакета приложения для Windows, находящуюся в виртуальной файловой системе. Это обеспечит, что приложение будет работать так, как если бы файлы DLL были установлены в папке System32/SysWOW64. В корне пакета создайте папку с именем VFS. В этой папке создайте папки SystemX64 и SystemX86. Затем поместите 32-разрядную версию DLL-файла в папку SystemX86, а 64-разрядную версию — в папку SystemX64.

  • Ваше приложение использует пакет платформы VCLibs. Для преобразования приложения Win32 на C++ необходимо развернуть среду выполнения Visual C++. Visual Studio 2019 и Windows SDK включают в себя самые новые пакеты платформы для версии 11.0, 12.0 и 14.0 среды выполнения Visual C++ в следующих папках.

    • Пакеты платформы VC 14.0: C:\Program Files (x86)\Microsoft SDKs\Windows Kits\10\ExtensionSDKs\Microsoft.VCLibs.Desktop\14.0.

    • Пакеты платформы VC 12.0: C:\Program Files (x86)\Microsoft SDKs\Windows Kits\10\ExtensionSDKs\Microsoft.VCLibs.Desktop.120\14.0.

    • Пакеты платформы VC 11.0: C:\Program Files (x86)\Microsoft SDKs\Windows Kits\10\ExtensionSDKs\Microsoft.VCLibs.Desktop.110\14.0.

    Чтобы использовать один из этих пакетов, необходимо сослаться на него как на зависимость в манифесте пакета. Когда пользователи будут устанавливать розничную версию приложения из Microsoft Store, пакет будет устанавливаться из Store вместе с приложением. При загрузке приложения зависимости не будут установлены. Чтобы установить зависимости вручную, необходимо установить соответствующий пакет платформы с помощью необходимого пакета APPX для архитектур x86, x64 или ARM в перечисленных выше папках установки.

    Чтобы создать ссылку на пакет платформы среды выполнения Visual C++ в приложении, выполните следующее:

    1. Перейдите в папку установки пакета платформы, указанную выше для версии среды выполнения Visual C++, используемой приложением.

    2. Откройте файл SDKManifest.xml в этой папке, перейдите к атрибуту FrameworkIdentity-Debug или FrameworkIdentity-Retail (в зависимости от того, используете вы отладочную или розничную версию среды выполнения) и скопируйте значения Name и MinVersion из этого атрибута. Например, ниже приведен атрибут FrameworkIdentity-Retail для текущего пакета платформы VC 14.0.

      FrameworkIdentity-Retail = "Name = Microsoft.VCLibs.140.00.UWPDesktop, MinVersion = 14.0.27323.0, Publisher = 'CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US'"
      
    3. В манифесте пакета приложения добавьте следующий элемент <PackageDependency> в узел <Dependencies>. Обязательно замените значения Name и MinVersion на значения, скопированные на предыдущем шаге. В следующем примере задается зависимость для текущей версии пакета платформы VC 14.0:

      <PackageDependency Name="Microsoft.VCLibs.140.00.UWPDesktop" MinVersion="14.0.27323.0" Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" />
      
  • Ваше приложение содержит настраиваемый список переходов. Списки переходов следует использовать с учетом некоторых известных проблем и особенностей.

    • Архитектура вашего приложения не соответствует операционной системе. Сейчас списки переходов работают неправильно при несоответствии архитектур приложения и операционной системы (например, при запуске приложения x86 в Windows x64). Единственное решение — перекомпиляция приложения в соответствующую архитектуру.

    • Ваше приложение создает элементы списка переходов и вызывает ICustomDestinationList::SetAppID или SetCurrentProcessExplicitAppUserModelID . Не задавайте свой AppID в коде программными средствами. Это приведет к тому, что элементы списка переходов не будут отображаться. Если вашему приложению требуется пользовательский идентификатор, укажите это с помощью файла манифеста. Инструкции см. в статье об упаковке классических приложений вручную. AppID для вашего приложения указан в разделе YOUR_PRAID_HERE.

    • Ваше приложение добавляет ссылку на оболочку списка переходов, которая ссылается на исполняемый файл в пакете. Напрямую запускать исполняемые файлы в пакете из списка переходов нельзя (за исключением абсолютного пути собственного файла .exe приложения). Вместо этого зарегистрируйте псевдоним выполнения приложения (который позволит вашему упакованному классическому приложению запускаться через ключевое слово, как будто оно находится в PATH) и задайте в качестве целевого пути ссылки путь к этому псевдониму. Дополнительные сведения об использовании расширения appExecutionAlias см. в статье Integrate your desktop app with Windows 10 (Интеграция классического приложения с Windows 10). Обратите внимание, что если требуется, чтобы ресурсы ссылки в списке переходов совпадали с исходным файлом .exe, необходимо задать ресурсы, такие как значок, используя SetIconLocation, а для отображения имени использовать PKEY_Title, так же, как и для других пользовательских записей.

    • Ваше приложение добавляет элементы списка переходов, которые ссылаются на ресурсы в пакете приложения по абсолютному пути. Путь установки приложения может измениться при обновлении пакета, изменении расположения ресурсов (например, значков, документов, исполняемых файлов и т. п.). Если элементы списка переходов ссылаются на такие ресурсы по абсолютным путям, то приложение должно периодически обновлять свой список переходов (например, при запуске приложения) для обеспечения правильности путей. Либо можно использовать API-интерфейсы UWP Windows.UI.StartScreen.JumpList, которые позволяют ссылаться на ресурсы строк и изображений с помощью схемы URI package-relative ms-resource (которая также поддерживает определение языка, DPI и высокой контрастности).

  • Для выполнения задач приложение запускает служебную программу. Избегайте запуска служебных программ командной строки, таких как PowerShell и Cmd.exe. Фактически, если пользователи устанавливают ваше приложение в системе под управлением Windows 10 S, то в дальнейшем ваше приложение не сможет запустить эти служебные программы вообще. Это может препятствовать отправке вашего приложения в Microsoft Store, так как все приложения, отправляемые туда, должны быть совместимы с Windows 10 S.

    Служебные программы часто предоставляют удобный способ для получения информации из операционной системы, доступа к реестру или к возможностям системы. Однако для выполнения такого рода задач можно использовать API UWP. Эти интерфейсы более производительны, так как для их запуска не требуется запуск отдельного исполняемого файла, но более важно то, что эти API не позволяют приложениям выходить за пределы пакета. Архитектура приложения будет по-прежнему отвечать требованиям к изоляции, доверию и безопасности, которые сопутствуют упакованному приложению, а поведение вашего приложения будет соответствовать поведению, принятому в системах под управлением Windows 10 S.

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

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

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

  • Приложение создает код. Приложение может генерировать код, который используется в памяти, но избегайте записи этого кода на диск, так как процесс сертификации приложений для Windows не сможет проверить этот код перед отправкой приложения. Кроме того, приложения, которые записывают код на диск, не будут работать правильно в системах под управлением Windows 10 S. Это может препятствовать отправке вашего приложения в Microsoft Store, так как все приложения, отправляемые туда, должны быть совместимы с Windows 10 S.

Важно!

После создания пакета приложения для Windows протестируйте свое приложение и убедитесь, что оно работает правильно в системах под управлением Windows 10 S. Все приложения, отправленные в Microsoft Store, должны быть совместимы с Windows 10 S. Несовместимые приложения не принимаются в Store. См. статью Тестирование приложения для Windows на Windows 10 S.