Delen via


Winapp CLI gebruiken met C++ en CMake

Deze handleiding laat zien hoe u de winapp CLI gebruikt met een C++-toepassing om fouten op te sporen met pakketidentiteit en uw toepassing als msix te verpakken.

Pakketidentiteit is een kernconcept in het Windows app model. Hiermee kan uw toepassing specifieke Windows-API's (zoals meldingen, beveiliging, AI-API's, enzovoort) access, een schone installatie-/verwijderingservaring hebben, en meer.

Een standaard uitvoerbaar bestand (zoals een bestand dat is gemaakt met cmake --build) heeft geen pakketidentiteit. In deze handleiding ziet u hoe u deze toevoegt voor foutopsporing en deze vervolgens inpakt voor distributie.

Vereiste voorwaarden

  1. Build Tools: Gebruik een compilerhulpprogrammaketen die wordt ondersteund door CMake. In dit voorbeeld wordt Visual Studio gebruikt. U kunt de communityversie installeren met:

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

    Start opnieuw op na de installatie.

  2. CMake: CMake installeren:

    winget install Kitware.CMake --source winget
    
  3. winapp CLI: Installeer de winapp CLI met winget:

    winget install Microsoft.winappcli --source winget
    

1. Een nieuwe C++-app maken

Begin met het maken van een eenvoudige C++-toepassing. Maak een nieuwe map voor uw project:

mkdir cpp-app
cd cpp-app

Maak een main.cpp bestand met een eenvoudig 'Hallo wereld!'-programma:

#include <iostream>

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

Maak een CMakeLists.txt bestand om de build te configureren:

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)

Bouw en voer het uit om ervoor te zorgen dat alles werkt:

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

2. Werk code bij om de identiteit te controleren

Werk de app bij om te controleren of deze wordt uitgevoerd met pakketidentiteit met behulp van de Windows Runtime C++-API.

Werk eerst uw CMakeLists.txt bij om een koppeling te maken met de Windows App Modelbibliotheek:

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)

Vervang vervolgens de inhoud van 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. Uitvoeren zonder identiteit

Bouw de app opnieuw en voer deze uit:

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

U ziet nu 'Niet verpakt'. Hiermee wordt bevestigd dat het standaard uitvoerbare bestand wordt uitgevoerd zonder pakketidentiteit.

4. Initialiseer project met winapp CLI

Met de opdracht winapp init stelt u alles in wat u nodig hebt: app-manifest, assets en optioneel Windows App SDK headers voor C++-ontwikkeling.

winapp init

Wanneer u hierom wordt gevraagd:

  • Pakketnaam: druk op Enter om de standaardwaarde te accepteren (cpp-app)
  • Publisher naam: Druk op Enter om de standaardinstelling te accepteren of voer uw naam in
  • Versie: Druk op Enter om 1.0.0.0 te accepteren
  • Toegangspunt: Druk op Enter om de standaardwaarde (cpp-app.exe) te accepteren
  • Setup SDK's: Selecteer 'Stabiele SDK's' om Windows App SDK te downloaden en headers te genereren

Met deze opdracht maakt u:

  • appxmanifest.xml en Assets map voor uw app-identiteit
  • Een map .winapp met Windows App SDK headers en bibliotheken
  • Een winapp.yaml configuratiebestand voor het vastmaken van SDK-versies

Debuggen met identiteit

Als u functies wilt testen waarvoor identiteit is vereist zonder de app volledig te verpakken, gebruikt u winapp create-debug-identity:

  1. Bouw het uitvoerbare bestand:

    cmake --build build --config Debug
    
  2. Debug-identiteit toepassen

    winapp create-debug-identity .\build\Debug\cpp-app.exe
    
  3. Voer het uitvoerbare bestand uit:

    .\build\Debug\cpp-app.exe
    

U ziet nu uitvoer die vergelijkbaar is met:

Package Family Name: cpp-app_12345abcde

Foutopsporingsidentiteit automatiseren (optioneel)

Voeg een post-build-opdracht toe aan uw CMakeLists.txt om automatisch de foutopsporingsidentiteit toe te passen.

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. Het gebruik van Windows App SDK (optioneel)

Als u hebt geselecteerd om de SDK's in te stellen tijdens winapp init, hebt u toegang tot de Windows App SDK-headers in de map .winapp/include.

Werk uw CMakeLists.txt bij om de headers op te nemen:

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

Werk main.cpp bij zodat het de Windows App Runtime-API gebruikt.

#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. Headers herstellen wanneer dat nodig is

De .winapp map wordt automatisch toegevoegd aan .gitignore. Wanneer anderen uw project klonen, moeten ze deze bestanden herstellen:

winapp restore
winapp cert generate --if-exists skip

8. Pakket met MSIX

Zodra u klaar bent om te distribueren, kunt u het pakket als MSIX verpakken:

  1. Build voor release:

    cmake --build build --config Release
    
  2. Pakketmap voorbereiden:

    mkdir dist
    copy .\build\Release\cpp-app.exe .\dist\
    
  3. Een ontwikkelingscertificaat genereren:

    winapp cert generate --if-exists skip
    
  4. Pakket en teken:

    winapp pack .\dist --cert .\devcert.pfx
    
  5. Installeer het certificaat (als beheerder uitvoeren):

    winapp cert install .\devcert.pfx
    
  6. Installeren en uitvoeren:

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

Aanbeveling

  • Onderteken uw MSIX met een certificaat voor ondertekening van programmacode van een certificeringsinstantie voor productiedistributie.
  • De Microsoft Store ondertekent de MSIX voor u. U hoeft de MSIX niet te ondertekenen voordat u deze inzendt.
  • Mogelijk hebt u afzonderlijke MSIX-pakketten nodig voor elke architectuur die u ondersteunt (x64, Arm64).