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


Использование winapp CLI с C++ и CMake

В этом руководстве показано, как использовать winapp CLI с приложением C++ для отладки с помощью удостоверения пакета и упаковки приложения в виде MSIX.

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

Стандартный исполняемый файл (например, созданный с cmake --build) не имеет удостоверения пакета. В этом руководстве показано, как добавить его для отладки, а затем упаковать его для распространения.

Необходимые условия

  1. Средства сборки. Использование цепочки инструментов компилятора, поддерживаемой CMake. В этом примере используется Visual Studio. Вы можете установить сообщественное издание следующим образом:

    winget install --id Microsoft.VisualStudio.Community --source winget --override "--add Microsoft.VisualStudio.Workload.NativeDesktop --includeRecommended --passive --wait"
    

    Перезагрузите после установки.

  2. CMake: установите CMake:

    winget install Kitware.CMake --source winget
    
  3. winapp CLI: Установите winapp с помощью winget:

    winget install Microsoft.winappcli --source winget
    

1. Создание нового приложения C++

Начните с создания простого приложения C++. Создайте новую директорию для вашего проекта:

mkdir cpp-app
cd cpp-app

main.cpp Создайте файл с базовой программой Hello, world!":

#include <iostream>

int main() {
    std::cout << "Hello, world!" << std::endl;
    return 0;
}

CMakeLists.txt Создайте файл для настройки сборки:

cmake_minimum_required(VERSION 3.20)
project(cpp-app)

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

add_executable(cpp-app main.cpp)

Выполните сборку и запустите ее, чтобы убедиться, что все работает:

cmake -B build
cmake --build build --config Debug
.\build\Debug\cpp-app.exe

2. Обновление кода для проверки удостоверения

Обновите приложение, чтобы определить, работает ли оно с идентификацией пакета с помощью API Windows Runtime C++.

Сначала обновите CMakeLists.txt, чтобы связать с библиотекой модели приложений Windows.

cmake_minimum_required(VERSION 3.20)
project(cpp-app)

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

add_executable(cpp-app main.cpp)

# Link Windows Runtime libraries
target_link_libraries(cpp-app PRIVATE WindowsApp.lib OneCoreUap.lib)

Затем замените содержимое main.cpp:

#include <iostream>
#include <windows.h>
#include <appmodel.h>

int main() {
    UINT32 length = 0;
    LONG result = GetCurrentPackageFamilyName(&length, nullptr);

    if (result == ERROR_INSUFFICIENT_BUFFER) {
        std::wstring familyName;
        familyName.resize(length);

        result = GetCurrentPackageFamilyName(&length, familyName.data());

        if (result == ERROR_SUCCESS) {
            std::wcout << L"Package Family Name: " << familyName.c_str() << std::endl;
        } else {
            std::wcout << L"Error retrieving Package Family Name" << std::endl;
        }
    } else {
        std::cout << "Not packaged" << std::endl;
    }

    return 0;
}

3. Запуск без идентификации

Перестройте и запустите приложение:

cmake --build build --config Debug
.\build\Debug\cpp-app.exe

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

4. Инициализируйте проект с помощью winapp CLI

Команда winapp init настраивает все необходимое: манифест приложения, ресурсы и при необходимости Windows App SDK заголовки для разработки C++.

winapp init

Когда появится запрос:

  • Имя пакета: нажмите Enter, чтобы принять значение по умолчанию (cpp-app)
  • Имя издателя: нажмите клавишу Enter, чтобы принять значение по умолчанию или введите своё имя.
  • Версия: нажмите клавишу ВВОД, чтобы принять 1.0.0.0
  • Точка входа: нажмите клавишу ВВОД, чтобы принять значение по умолчанию (cpp-app.exe)
  • Настройка SDK: Выберите "Стабильные SDK", чтобы скачать Windows App SDK и сгенерировать заголовки

Эта команда создает следующее:

  • appxmanifest.xml и Assets папки для идентификации приложения
  • Папка .winapp с заголовками и библиотеками Windows App SDK
  • Файл конфигурации winapp.yaml для фиксации версий SDK

5. Отладка с идентификацией

Чтобы протестировать функции, требующие удостоверения без полной упаковки приложения, используйте winapp create-debug-identityследующую команду:

  1. Создайте исполняемый файл:

    cmake --build build --config Debug
    
  2. Применить идентификатор отладки:

    winapp create-debug-identity .\build\Debug\cpp-app.exe
    
  3. Запустите исполняемый файл:

    .\build\Debug\cpp-app.exe
    

Теперь вы увидите выходные данные, аналогичные следующим:

Package Family Name: cpp-app_12345abcde

Автоматизация идентификации отладки (необязательно)

Добавьте команду после сборки в CMakeLists.txt, чтобы автоматически применять отладочный идентификатор:

add_custom_command(TARGET cpp-app POST_BUILD
    COMMAND $<$<CONFIG:Debug>:winapp>
            $<$<CONFIG:Debug>:create-debug-identity>
            $<$<CONFIG:Debug>:$<TARGET_FILE:cpp-app>>
    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
    COMMAND_EXPAND_LISTS
    COMMENT "Applying debug identity to executable..."
)

6. Использование Windows App SDK (необязательно)

Если вы выбрали настройку пакетов SDK во время winapp init, у вас есть доступ к заголовкам Windows App SDK в папке .winapp/include.

Обновите CMakeLists.txt, чтобы добавить заголовки.

# Add Windows App SDK include directory
target_include_directories(cpp-app PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/.winapp/include)

Обновите main.cpp, чтобы использовать Windows App Runtime API.

#include <iostream>
#include <windows.h>
#include <appmodel.h>
#include <winrt/Microsoft.Windows.ApplicationModel.WindowsAppRuntime.h>

int main() {
    winrt::init_apartment();

    UINT32 length = 0;
    LONG result = GetCurrentPackageFamilyName(&length, nullptr);

    if (result == ERROR_INSUFFICIENT_BUFFER) {
        std::wstring familyName;
        familyName.resize(length);

        result = GetCurrentPackageFamilyName(&length, familyName.data());

        if (result == ERROR_SUCCESS) {
            std::wcout << L"Package Family Name: " << familyName.c_str() << std::endl;

            auto runtimeVersion = winrt::Microsoft::Windows::ApplicationModel::WindowsAppRuntime::RuntimeInfo::AsString();
            std::wcout << L"Windows App Runtime Version: " << runtimeVersion.c_str() << std::endl;
        }
    } else {
        std::cout << "Not packaged" << std::endl;
    }

    return 0;
}

7. Восстановление заголовков при необходимости

Папка .winapp автоматически добавляется в .gitignore. Когда другие клонируют ваш проект, им необходимо восстановить следующие файлы:

winapp restore
winapp cert generate --if-exists skip

8. Пакет с MSIX

После того как будете готовы к распространению, упакуйте как MSIX.

  1. Сборка для релиза:

    cmake --build build --config Release
    
  2. Подготовка каталога пакета:

    mkdir dist
    copy .\build\Release\cpp-app.exe .\dist\
    
  3. Создайте сертификат разработки:

    winapp cert generate --if-exists skip
    
  4. Пакет и знак:

    winapp pack .\dist --cert .\devcert.pfx
    
  5. Установите сертификат (запуск от имени администратора):

    winapp cert install .\devcert.pfx
    
  6. Установка и запуск:

    Add-AppxPackage .\cpp-app.msix
    cpp-app
    

Подсказка

  • Подпишите свой MSIX сертификатом подписи кода из центра сертификации для промышленного распространения.
  • Microsoft Store подписывает MSIX для вас, не нужно подписывать перед отправкой.
  • Вам могут потребоваться отдельные пакеты MSIX для каждой поддерживаемой архитектуры (x64, Arm64).