Partager via


Utilisation de winapp CLI avec C++ et CMake

Ce guide montre comment utiliser l’interface CLI winapp avec une application C++ pour déboguer avec l’identité de package et empaqueter votre application en tant que MSIX.

L’identité de package est un concept de base dans le modèle Windows app. Il permet à votre application d'accéder à des API Windows spécifiques (telles que les notifications, les API de sécurité, les API IA, etc.), d'avoir une expérience d'installation/désinstallation optimisée, et bien plus encore.

Un exécutable standard (tel qu’un fichier créé avec cmake --build) n’a pas d’identité de package. Ce guide montre comment l’ajouter pour le débogage, et ensuite l'emballer pour la distribution.

Prerequisites

  1. Outils de génération : utilisez une chaîne d’outils du compilateur prise en charge par CMake. Cet exemple utilise Visual Studio. Vous pouvez installer l’édition community avec :

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

    Redémarrez après l’installation.

  2. CMake : Installer CMake :

    winget install Kitware.CMake --source winget
    
  3. winapp CLI : Installez l’outil en ligne de commande winapp via winget :

    winget install Microsoft.winappcli --source winget
    

1. Créer une application C++

Commencez par créer une application C++ simple. Créez un répertoire pour votre project :

mkdir cpp-app
cd cpp-app

Créez un main.cpp fichier avec un programme « Hello, world ! » de base :

#include <iostream>

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

Créez un CMakeLists.txt fichier pour configurer la build :

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)

Générez et exécutez-le pour vous assurer que tout fonctionne :

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

2. Mettre à jour le code pour vérifier l’identité

Mettez à jour l'application pour vérifier s'il est en cours d'exécution avec l'identité de package à l'aide de l'API Windows Runtime C++.

Tout d’abord, mettez à jour votre CMakeLists.txt pour établir un lien vers la bibliothèque de modèles Windows App :

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)

Ensuite, remplacez le contenu de 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. Exécuter sans identité

Régénérez et exécutez l’application :

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

Vous devez voir « Non empaqueté ». Cela confirme que l’exécutable standard est en cours d’exécution sans identité de package.

4. Initialisez le projet avec l'outil CLI winapp

La commande winapp init configure tout ce dont vous avez besoin : manifeste d’application, ressources et éventuellement Windows App SDK en-têtes pour le développement C++.

winapp init

Lorsque vous y êtes invité :

  • Nom du package : appuyez sur Entrée pour accepter la valeur par défaut (cpp-app)
  • Publisher nom : appuyez sur Entrée pour accepter la valeur par défaut ou entrer votre nom
  • Version : appuyez sur Entrée pour accepter la version 1.0.0.0
  • Point d’entrée : appuyez sur Entrée pour accepter la valeur par défaut (cpp-app.exe)
  • Setup SDK : sélectionnez « Sdk stables » pour télécharger Windows App SDK et générer des en-têtes

Cette commande crée :

  • appxmanifest.xml et Assets dossier d'identité de votre application
  • Un dossier .winapp contenant des en-têtes et des bibliothèques Windows App SDK
  • Fichier winapp.yaml de configuration pour l’épinglage des versions du Kit de développement logiciel (SDK)

5. Déboguer avec l’identité

Pour tester les fonctionnalités qui nécessitent une identité sans empaqueter entièrement l’application, utilisez winapp create-debug-identity:

  1. Générez l’exécutable :

    cmake --build build --config Debug
    
  2. Appliquer l’identité de débogage :

    winapp create-debug-identity .\build\Debug\cpp-app.exe
    
  3. Exécutez l’exécutable :

    .\build\Debug\cpp-app.exe
    

Vous devez maintenant voir un résultat semblable à :

Package Family Name: cpp-app_12345abcde

Automatisation de l'identité de debug (facultatif)

Ajoutez une commande post-build à votre CMakeLists.txt pour appliquer automatiquement l’identité de débogage :

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. Utilisation de Windows App SDK (facultatif)

Si vous avez sélectionné de configurer les SDK pendant winapp init, vous avez accès aux en-têtes du SDK d'applications Windows dans le dossier .winapp/include.

Mettez à jour votre CMakeLists.txt pour y inclure les en-têtes :

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

Mettez à jour main.cpp pour utiliser l'API Windows App Runtime :

#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. Restaurer des en-têtes si nécessaire

Le .winapp dossier est automatiquement ajouté à .gitignore. Lorsque d’autres clonent votre project, ils doivent restaurer ces fichiers :

winapp restore
winapp cert generate --if-exists skip

8. Package avec MSIX

Une fois que vous êtes prêt à distribuer, empaqueter en tant que MSIX :

  1. Build pour la mise en production :

    cmake --build build --config Release
    
  2. Préparer le répertoire du package :

    mkdir dist
    copy .\build\Release\cpp-app.exe .\dist\
    
  3. Générez un certificat de développement :

    winapp cert generate --if-exists skip
    
  4. Empaqueter et signer :

    winapp pack .\dist --cert .\devcert.pfx
    
  5. Installez le certificat (exécuté en tant qu’administrateur) :

    winapp cert install .\devcert.pfx
    
  6. Installez et exécutez :

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

Conseil / Astuce

  • Signez votre MSIX avec un certificat de signature de code auprès d’une autorité de certification pour la distribution de production.
  • Le Microsoft Store signe MSIX pour vous, il n’est pas nécessaire de vous connecter avant la soumission.
  • Vous pouvez avoir besoin de packages MSIX distincts pour chaque architecture prise en charge (x64, Arm64).