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

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

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

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

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

Платформа поддержки пакетов

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

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

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

Внедрение библиотеки DLL для платформы поддержки пакетов

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

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

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

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

Фильтр приложений ProcMon

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

События ProcMon

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

Успешное исключение ProcMon

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

ProcMon Config.txt

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

Config.txtприложений

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

Файл журнала ProcMon

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

Шаг 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

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

Макет пакета

Если у вас нет 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

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

Двоичные файлы пакетов

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

Откройте манифест пакета в текстовом редакторе, а затем задайте 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:

Array ключ Значение
веб-масштабированием; идентификатор Используйте значение Id атрибута Application элемента в манифесте пакета.
веб-масштабированием; исполняемый файл Относительный путь к исполняемому файлу, который требуется запустить. В большинстве случаев это значение можно получить из файла манифеста пакета перед изменением. Это значение Executable атрибута Application элемента.
веб-масштабированием; WorkingDirectory (Необязательно) Относительный путь к пакету, используемый в качестве рабочего каталога запуска приложения. Если это значение не задано, операционная система использует System32 каталог в качестве рабочего каталога приложения.
процессы исполняемый файл В большинстве случаев это будет имя настроенного 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 не найден

Отказано в доступе TraceShim

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

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

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

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

Завершенное решение

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

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

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

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

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

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

Пустое решение

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

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

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

Шаблон проекта пакета

Дополнительные сведения о проекте упаковки приложений 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>

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

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

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

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

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

Параметр ISO 17

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

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

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

Пакет nuget

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

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

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

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

Пустой проект

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

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

Справочник по средствам запуска PSF

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

Справочник по исправлению среды выполнения

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

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

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

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

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

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

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

Примечание

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

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

Задать как точку входа

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

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

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

Array ключ Значение
веб-масштабированием; идентификатор Используйте значение Id атрибута Application элемента в манифесте пакета.
веб-масштабированием; исполняемый файл Относительный путь к исполняемому файлу, который требуется запустить. В большинстве случаев это значение можно получить из файла манифеста пакета перед изменением. Это значение Executable атрибута Application элемента.
веб-масштабированием; WorkingDirectory (Необязательно) Относительный путь к пакету, используемый в качестве рабочего каталога запуска приложения. Если это значение не задано, операционная система использует System32 каталог в качестве рабочего каталога приложения.
процессы исполняемый файл В большинстве случаев это будет имя настроенного 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 из пакета Windows SDK, как описано выше. Кроме того, в Visual Studio щелкните правой кнопкой мыши узел проекта приложения и выберите "Магазин —> создать пакеты приложений".

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

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