Начало работы с платформой поддержки пакетов

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

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

Общие сведения о том, что находится в платформе поддержки пакетов

Платформа поддержки пакетов содержит исполняемый файл, библиотеку DLL диспетчера среды выполнения и набор исправлений для среды выполнения.

Package Support Framework

Ниже приведен процесс.

  1. Создайте файл конфигурации, указывающий исправления, которые необходимо применить к приложению.
  2. Измените пакет, чтобы указать исполняемый файл средства поддержки пакетов (PSF).

Когда пользователи запускают приложение, средство запуска платформы поддержки пакетов — это первый исполняемый файл, который запускается. Он считывает файл конфигурации и внедряет исправления среды выполнения и библиотеку DLL диспетчера среды выполнения в процесс приложения. Диспетчер среды выполнения применяет исправление, когда это требуется для выполнения приложения в контейнере MSIX.

Package Support Framework DLL Injection

Шаг 1. Определение проблем совместимости упакованных приложений

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

Использование монитора процессов для выявления проблемы

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

ProcMon App Filter

Появится список событий. Во многих из этих событий слово SUCCESS появится в столбце "Результат ".

ProcMon Events

При необходимости можно отфильтровать события только для отображения только сбоев.

ProcMon Exclude Success

Если подозревается сбой доступа к файловой системе, выполните поиск событий сбоя, которые находятся в папке System32/SysWOW64 или пути к файлу пакета. Фильтры также могут помочь здесь. Начните в нижней части этого списка и прокрутите вверх. Ошибки, которые отображаются в нижней части этого списка, произошли в последнее время. Обратите внимание на ошибки, содержащие строки, такие как "доступ запрещен", и "путь/имя не найдено", и игнорируйте вещи, которые не выглядят подозрительными. PSFSample имеет две проблемы. Эти проблемы отображаются в списке, который отображается на следующем рисунке.

ProcMon Config.txt

В первой проблеме, которая отображается на этом изображении, приложение не считывается из файла Config.txt, расположенного в пути "C:\Windows\SysWOW64". Вряд ли приложение пытается ссылаться на этот путь напрямую. Скорее всего, он пытается прочитать из этого файла с помощью относительного пути, и по умолчанию "System32/SysWOW64" — рабочий каталог приложения. Это предполагает, что приложение ожидает, что текущий рабочий каталог будет установлен где-то в пакете. Глядя внутри appx, мы видим, что файл существует в том же каталоге, что и исполняемый файл.

App Config.txt

Вторая проблема отображается на следующем рисунке.

ProcMon Logfile

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

Шаг 2. Поиск исправления среды выполнения

PSF содержит исправления среды выполнения, которые можно использовать прямо сейчас, например исправление перенаправления файлов.

Исправление перенаправления файлов

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

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

Исправления среды выполнения из сообщества

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

Шаг 3. Применение исправления среды выполнения

Вы можете применить существующее исправление среды выполнения с несколькими простыми инструментами из пакета SDK для Windows и выполните следующие действия.

  • Создание папки макета пакета
  • Получение файлов платформы поддержки пакетов
  • Добавление их в пакет
  • Изменение манифеста пакета
  • Создание файла конфигурации

Давайте рассмотрим каждую задачу.

Создание папки макета пакета

Если у вас уже есть MSIX-файл (или APPX), его содержимое можно распаковывать в папку макета, которая будет служить промежуточной областью для пакета. Это можно сделать из командной строки с помощью средства MakeAppx. на основе пути установки пакета SDK вы найдете средство makeappx.exe на компьютере с Windows 10: x86: C:\Program Files (x86)\Windows Kits\10\bin\x86\makeappx.exe x64: C:\Program Files (x86)\Windows Kits\10\bin\x64\makeappx.exe

makeappx unpack /p PSFSamplePackage_1.0.60.0_AnyCPU_Debug.msix /d PackageContents

Это даст вам что-то, что выглядит следующим образом.

Package Layout

Если у вас нет MSIX-файла (или APPX), можно создать папку и файлы пакета с нуля.

Получение файлов платформы поддержки пакетов

Пакет Nuget PSF можно получить с помощью автономного средства командной строки Nuget или Visual Studio.

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

Установите средство командной строки Nuget из этого расположения: https://www.nuget.org/downloads Затем в командной строке Nuget выполните следующую команду:

nuget install Microsoft.PackageSupportFramework

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

Получение пакета с помощью Visual Studio

В Visual Studio щелкните правой кнопкой мыши узел решения или проекта и выберите одну из команд управления пакетами Nuget. Найдите пакет Microsoft.PackageSupportFramework или PSF, чтобы найти пакет на Nuget.org. Затем установите его.

Добавление файлов платформы поддержки пакетов в пакет

Добавьте необходимые 32-разрядные и 64-разрядные библиотеки DLL PSF и исполняемые файлы в каталог пакетов. Используйте следующую таблицу для справки. Вы также хотите включить все необходимые исправления среды выполнения. В нашем примере нам нужен исправление среды выполнения перенаправления файлов.

Исполняемый файл приложения — x64 Исполняемый файл приложения — x86
PSFLauncher64.exe PSFLauncher32.exe
PSFRuntime64.dll PSFRuntime32.dll
PSFRunDll64.exe PSFRunDll32.exe

Содержимое пакета должно выглядеть примерно так.

Package Binaries

Изменение манифеста пакета

Откройте манифест пакета в текстовом редакторе, а затем задайте Executable атрибут Application элемента именем исполняемого файла средства запуска PSF. Если вы знаете архитектуру целевого приложения, выберите соответствующую версию PSFLauncher32.exe или PSFLauncher64.exe. Если нет, PSFLauncher32.exe будет работать во всех случаях. Рассмотрим пример.

<Package ...>
  ...
  <Applications>
    <Application Id="PSFSample"
                 Executable="PSFLauncher32.exe"
                 EntryPoint="Windows.FullTrustApplication">
      ...
    </Application>
  </Applications>
</Package>

Создание файла конфигурации

Создайте имя config.jsonфайла и сохраните этот файл в корневую папку пакета. Измените объявленный идентификатор приложения файла config.json, чтобы указать исполняемый файл, который вы только что заменили. Используя знания, полученные с помощью монитора процессов, можно также задать рабочий каталог, а также использовать исправление перенаправления файлов для перенаправления операций чтения и записи в файлы log в каталоге PSFSampleApp относительно пакета.

{
    "applications": [
        {
            "id": "PSFSample",
            "executable": "PSFSampleApp/PSFSample.exe",
            "workingDirectory": "PSFSampleApp/"
        }
    ],
    "processes": [
        {
            "executable": "PSFSample",
            "fixups": [
                {
                    "dll": "FileRedirectionFixup.dll",
                    "config": {
                        "redirectedPaths": {
                            "packageRelative": [
                                {
                                    "base": "PSFSampleApp/",
                                    "patterns": [
                                        ".*\\.log"
                                    ]
                                }
                            ]
                        }
                    }
                }
            ]
        }
    ]
}

Ниже приведено руководство по схеме config.json:

Массив key Значение
applications id Используйте значение Id атрибута Application элемента в манифесте пакета.
applications executable Относительный путь пакета к исполняемому файлу, который требуется запустить. В большинстве случаев вы можете получить это значение из файла манифеста пакета, прежде чем изменять его. Это значение Executable атрибута Application элемента.
applications WorkingDirectory (Необязательно) Относительный путь к пакету, используемый в качестве рабочего каталога запуска приложения. Если это значение не задано, операционная система использует System32 каталог в качестве рабочего каталога приложения.
процессы executable В большинстве случаев это будет имя настроенного executable выше с удаленным путем и расширением файла.
Исправлений dll Относительный к пакету путь к исправлению, msix/.appx для загрузки.
Исправлений config (Необязательно) Управляет поведением библиотеки dll исправления. Точный формат этого значения зависит от исправления по исправлению, так как каждое исправление может интерпретировать этот "большой двоичный объект" по мере необходимости.

processesКлючи applicationsи fixups ключи являются массивами. Это означает, что файл config.json можно использовать для указания нескольких приложений, процессов и библиотеки DLL исправления.

Упаковка и тестирование приложения

Затем создайте пакет.

makeappx pack /d PackageContents /p PSFSamplePackageFixup.msix

Затем подпишите его.

signtool sign /a /v /fd sha256 /f ExportedSigningCertificate.pfx PSFSamplePackageFixup.msix

Дополнительные сведения см. в статье о создании сертификата подписи пакета и о том, как подписать пакет с помощью средства подписи

С помощью PowerShell установите пакет.

Примечание.

Сначала не забудьте удалить пакет.

powershell Add-AppPackage .\PSFSamplePackageFixup.msix

Запустите приложение и просмотрите поведение с примененным исправлением среды выполнения. Повторите шаги диагностики и упаковки по мере необходимости.

Проверьте, запущена ли платформа поддержки пакетов

Вы можете проверка, выполняется ли исправление среды выполнения. Это можно сделать, чтобы открыть диспетчер задач и нажать кнопку "Дополнительные сведения". Найдите приложение, к которому была применена платформа поддержки пакетов, и разверните подробные сведения о приложении, чтобы получить дополнительные сведения. Вы должны увидеть, что платформа поддержки пакетов запущена.

Использование исправления трассировки

Альтернативным способом диагностики проблем совместимости упакованных приложений является использование средства исправления трассировки. Эта библиотека DLL включается в PSF и предоставляет подробное диагностическое представление о поведении приложения, аналогичном монитору процессов. Он специально предназначен для выявления проблем совместимости приложений. Чтобы использовать исправление трассировки, добавьте библиотеку DLL в пакет, добавьте следующий фрагмент в файл config.json, а затем пакет и установите приложение.

{
    "dll": "TraceFixup.dll",
    "config": {
        "traceLevels": {
            "filesystem": "allFailures"
        }
    }
}

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

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

TraceShim File Not Found

TraceShim Access Denied

Отладка, расширение или создание исправления среды выполнения

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

  • Добавление проекта упаковки
  • Добавление проекта для исправления среды выполнения
  • Добавление проекта, запускающего исполняемый файл средства запуска PSF
  • Настройка проекта упаковки

Когда вы закончите, решение будет выглядеть примерно так.

Completed solution

Рассмотрим каждый проект в этом примере.

Project Назначение
DesktopApplicationPackage Этот проект основан на проекте упаковки приложений Windows и выводит пакет MSIX.
Runtimefix Это проект динамической библиотеки C++ с одной или несколькими функциями замены, которые служат в качестве исправления среды выполнения.
PSFLauncher Это пустой проект C++ . Этот проект — это место для сбора распространяемых файлов среды выполнения платформы поддержки пакетов. Он выводит исполняемый файл. Этот исполняемый файл — это первое, что выполняется при запуске решения.
WinFormsDesktopApplication Этот проект содержит исходный код классического приложения.

Полный пример, содержащий все эти типы проектов, см. в разделе PSFSample.

Давайте рассмотрим шаги по созданию и настройке каждого из этих проектов в решении.

Создание решения пакета

Если у вас еще нет решения для классического приложения, создайте новое пустое решение в Visual Studio.

Blank solution

Вы также можете добавить все проекты приложений, которые у вас есть.

Добавление проекта упаковки

Если у вас еще нет проекта упаковки приложений Windows, создайте его и добавьте его в решение.

Package project template

Дополнительные сведения о проекте упаковки приложений Windows см. в статье "Упаковка приложения" с помощью Visual Studio.

В Обозреватель решений щелкните правой кнопкой мыши проект упаковки, выберите пункт "Изменить", а затем добавьте его в нижней части файла проекта:

<Target Name="PSFRemoveSourceProject" AfterTargets="ExpandProjectReferences" BeforeTargets="_ConvertItems">
<ItemGroup>
  <FilteredNonWapProjProjectOutput Include="@(_FilteredNonWapProjProjectOutput)">
  <SourceProject Condition="'%(_FilteredNonWapProjProjectOutput.SourceProject)'=='<your runtime fix project name goes here>'" />
  </FilteredNonWapProjProjectOutput>
  <_FilteredNonWapProjProjectOutput Remove="@(_FilteredNonWapProjProjectOutput)" />
  <_FilteredNonWapProjProjectOutput Include="@(FilteredNonWapProjProjectOutput)" />
</ItemGroup>
</Target>

Добавление проекта для исправления среды выполнения

Добавьте проект библиотеки динамической компоновки C++ (DLL) в решение.

Runtime fix library

Щелкните правой кнопкой мыши этот проект и выберите пункт "Свойства".

На страницах свойств найдите поле "Стандартный язык C++", а затем в раскрывающемся списке рядом с этим полем выберите параметр ISO C++17 Standard (/std:c++17).

ISO 17 Option

Щелкните правой кнопкой мыши этот проект, а затем в контекстном меню выберите параметр "Управление пакетами Nuget". Убедитесь, что для параметра источника пакета задано значение All или nuget.org.

Щелкните значок параметров рядом с этим полем.

Найдите пакет Nuget PSF* и установите его для этого проекта.

nuget package

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

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

Добавление проекта, запускающего исполняемый файл средства запуска PSF

Добавьте в решение проект пустого проекта C++ .

Empty project

Добавьте пакет Nuget PSF в этот проект, используя те же инструкции, которые описаны в предыдущем разделе.

Откройте страницы свойств проекта и на странице "Общие параметры" задайте для свойства Target Name значение PSFLauncher32 или PSFLauncher64 в зависимости от архитектуры приложения.

PSF Launcher reference

Добавьте ссылку на проект по исправлению среды выполнения в решении.

runtime fix reference

Щелкните правой кнопкой мыши ссылку, а затем в окне свойств примените эти значения.

Свойство Значение
Копирование локального Истина
Копировать локальные вспомогательные сборки Истина
Выходные данные ссылочной сборки Истина
Компоновать зависимости библиотек False
Входные данные зависимостей библиотеки ссылок False

Настройка проекта упаковки

В проекте упаковки щелкните правой кнопкой мыши папку "Приложения " и выберите команду "Добавить ссылку".

Add Project Reference

Выберите проект средства запуска PSF и проект классического приложения, а затем нажмите кнопку "ОК ".

Desktop project

Примечание.

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

На узле "Приложения" щелкните правой кнопкой мыши приложение средства запуска PSF и выберите "Задать в качестве точки входа".

Set entry point

Добавьте файл с именем config.json в проект упаковки, а затем скопируйте и вставьте следующий текст JSON в файл. Задайте для свойства "Действие пакета" значение Content.

{
    "applications": [
        {
            "id": "",
            "executable": "",
            "workingDirectory": ""
        }
    ],
    "processes": [
        {
            "executable": "",
            "fixups": [
                {
                    "dll": "",
                    "config": {
                    }
                }
            ]
        }
    ]
}

Укажите значение для каждого ключа. Используйте эту таблицу в качестве справочника.

Массив key Значение
applications id Используйте значение Id атрибута Application элемента в манифесте пакета.
applications executable Относительный путь пакета к исполняемому файлу, который требуется запустить. В большинстве случаев вы можете получить это значение из файла манифеста пакета, прежде чем изменять его. Это значение Executable атрибута Application элемента.
applications WorkingDirectory (Необязательно) Относительный путь к пакету, используемый в качестве рабочего каталога запуска приложения. Если это значение не задано, операционная система использует System32 каталог в качестве рабочего каталога приложения.
процессы executable В большинстве случаев это будет имя настроенного executable выше с удаленным путем и расширением файла.
Исправлений dll Относительный путь к библиотеке DLL исправления для загрузки.
Исправлений config (Необязательно) Управляет поведением библиотеки DLL исправления. Точный формат этого значения зависит от исправления по исправлению, так как каждое исправление может интерпретировать этот "большой двоичный объект" по мере необходимости.

По завершении файл config.json будет выглядеть примерно так.

{
  "applications": [
    {
      "id": "DesktopApplication",
      "executable": "DesktopApplication/WinFormsDesktopApplication.exe",
      "workingDirectory": "WinFormsDesktopApplication"
    }
  ],
  "processes": [
    {
      "executable": ".*App.*",
      "fixups": [ { "dll": "RuntimeFix.dll" } ]
    }
  ]
}

Примечание.

processesКлючи applicationsи fixups ключи являются массивами. Это означает, что файл config.json можно использовать для указания нескольких приложений, процессов и библиотеки DLL исправления.

Отладка исправления среды выполнения

В Visual Studio нажмите клавишу F5, чтобы запустить отладчик. Первое, что начинается, — это приложение средства запуска PSF, которое, в свою очередь, запускает целевое классическое приложение. Чтобы выполнить отладку целевого классического приложения, необходимо вручную подключиться к процессу классического приложения, выбрав "Отладка в> процесс" и выбрав процесс приложения. Чтобы разрешить отладку приложения .NET с помощью библиотеки DLL для собственной среды выполнения, выберите управляемые и машинные типы кода (отладка в смешанном режиме).

После настройки этого можно задать точки останова рядом со строками кода в коде классического приложения и проекте исправления среды выполнения. Если в приложении нет исходного кода, вы сможете задать точки останова только рядом со строками кода в проекте исправления среды выполнения.

Так как отладка F5 запускает приложение путем развертывания свободных файлов из пути к папке макета пакета, а не установки из пакета .msix/.appx, папка макета обычно не имеет одинаковых ограничений безопасности, что и установленная папка пакета. В результате может быть невозможно воспроизвести ошибки отказа доступа к пути пакета перед применением исправления среды выполнения.

Чтобы устранить эту проблему, используйте развертывание пакета .msix/ .appx, а не развертывание свободного файла F5. Чтобы создать файл пакета MSIX /APPX, используйте служебную программу MakeAppx из пакета SDK для Windows, как описано выше. Кроме того, в Visual Studio щелкните правой кнопкой мыши узел проекта приложения и выберите Store —> создать пакеты приложений.

Другая проблема с Visual Studio заключается в том, что она не поддерживает встроенное подключение к дочерним процессам, запущенным отладчиком. Это затрудняет отладку логики в пути запуска целевого приложения, которое должно быть присоединено Visual Studio вручную после запуска.

Чтобы устранить эту проблему, используйте отладчик, поддерживающий присоединение дочернего процесса. Обратите внимание, что обычно невозможно подключить JIT-отладчик к целевому приложению. Это связано с тем, что большинство методов JIT включают запуск отладчика вместо целевого приложения с помощью раздела реестра ImageFileExecutionOptions. Это побеждает механизм обхода, используемый PSFLauncher.exe для внедрения FixupRuntime.dll в целевое приложение. WinDbg, включенный в средства отладки для Windows и полученный из пакета SDK для Windows, поддерживает присоединение дочернего процесса. Она также теперь поддерживает непосредственное запуск и отладку приложения UWP.

Чтобы выполнить отладку целевого приложения, запускаемого в качестве дочернего процесса, запустите WinDbg.

windbg.exe -plmPackage PSFSampleWithFixup_1.0.59.0_x86__7s220nvg1hg3m -plmApp PSFSample

В командной строке WinDbg включите дочернюю отладку и задайте соответствующие точки останова.

.childdbg 1
g

(выполняется до запуска целевого приложения и разрывается в отладчике)

sxe ld fixup.dll
g

(выполнение до загрузки библиотеки DLL исправления)

bp ...

Примечание.

PLMDebug также можно использовать для подключения отладчика к приложению при запуске, а также включается в средства отладки для Windows. Однако более сложно использовать, чем прямая поддержка, предоставляемая WinDbg.

Поддержка

Есть вопросы? Попросите нас о беседе платформы поддержки пакетов на сайте технического сообщества MSIX.