Condividi tramite


Uso dell'interfaccia della riga di comando di winapp con C++ e CMake

Questa guida illustra come usare l'interfaccia della riga di comando di winapp con un'applicazione C++ per eseguire il debug con l'identità del pacchetto e creare un pacchetto dell'applicazione come MSIX.

L'identità del pacchetto è un concetto di base nel modello di Windows app. Consente all'applicazione di access API Windows specifiche (ad esempio Notifiche, Sicurezza, API di intelligenza artificiale e così via), avere un'esperienza di installazione/disinstallazione pulita e altro ancora.

Un eseguibile standard (come quello creato con cmake --build) non ha un'identità del pacchetto. Questa guida illustra come aggiungerlo per il debug e quindi crearne il pacchetto per la distribuzione.

Prerequisiti

  1. Strumenti di compilazione: usare una toolchain del compilatore supportata da CMake. Questo esempio usa Visual Studio. È possibile installare l'edizione community con:

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

    Riavviare dopo l'installazione.

  2. CMake: Installare CMake:

    winget install Kitware.CMake --source winget
    
  3. CLI winapp: installare il winapp CLI tramite winget:

    winget install Microsoft.winappcli --source winget
    

1. Creare una nuova app C++

Per iniziare, creare una semplice applicazione C++. Creare una nuova directory per il project:

mkdir cpp-app
cd cpp-app

Creare un main.cpp file con un programma "Hello, world!" di base:

#include <iostream>

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

Creare un CMakeLists.txt file per configurare la compilazione:

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)

Compila ed eseguilo per assicurarti che tutto funzioni:

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

2. Aggiornare il codice per verificare l'identità

Aggiornare l'app per verificare se è in esecuzione con l'identità del pacchetto usando l'API C++ Windows Runtime.

Prima di tutto, aggiorna il CMakeLists.txt per collegarlo alla libreria Windows App Model.

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)

Sostituire quindi il contenuto di 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. Eseguire senza identità

Ricompilare ed eseguire l'app:

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

Verrà visualizzato il messaggio "Non incluso nel pacchetto". Ciò conferma che l'eseguibile standard è in esecuzione senza alcuna identità del pacchetto.

4. Inizializzare il progetto con la CLI di winapp

Il comando winapp init configura tutto il necessario: manifest dell'app, asset, e opzionalmente le intestazioni di Windows App SDK per lo sviluppo C++.

winapp init

Quando richiesto:

  • Nome pacchetto: premere INVIO per accettare il valore predefinito (cpp-app)
  • Publisher nome: premere INVIO per accettare il valore predefinito o immettere il nome
  • Versione: premere INVIO per accettare 1.0.0.0
  • Punto di ingresso: premere INVIO per accettare il valore predefinito (cpp-app.exe)
  • Setup SDK: selezionare "SDK stabili" per scaricare Windows App SDK e generare intestazioni

Questo comando crea:

  • appxmanifest.xml e Assets cartella per l'identità dell'app
  • Una cartella .winapp con intestazioni e librerie Windows App SDK
  • Un winapp.yaml file di configurazione per il blocco delle versioni dell'SDK

5. Eseguire il debug con l'identità

Per testare le funzionalità che richiedono l'identità senza creare completamente il pacchetto dell'app, usare winapp create-debug-identity:

  1. Compilare il file eseguibile:

    cmake --build build --config Debug
    
  2. Applicare l'identità di debug:

    winapp create-debug-identity .\build\Debug\cpp-app.exe
    
  3. Eseguire il file eseguibile:

    .\build\Debug\cpp-app.exe
    

Verrà ora visualizzato un output simile al seguente:

Package Family Name: cpp-app_12345abcde

Automazione dell'identità di debug (facoltativo)

Aggiungi un comando post-compilazione al tuo CMakeLists.txt per applicare automaticamente l'identità di debug:

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. Uso di Windows App SDK (facoltativo)

Se si è scelto di installare gli SDK durante winapp init, si ha accesso alle intestazioni di Windows App SDK nella cartella .winapp/include.

Aggiorna CMakeLists.txt per includere le intestazioni:

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

Aggiornare main.cpp per usare l'API di 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. Ripristinare le intestazioni quando necessario

La .winapp cartella viene aggiunta automaticamente a .gitignore. Quando altri clonano il project, devono ripristinare questi file:

winapp restore
winapp cert generate --if-exists skip

8. Pacchetto con MSIX

Una volta pronti per la distribuzione, creare un pacchetto come MSIX:

  1. Compilazione per il rilascio:

    cmake --build build --config Release
    
  2. Preparare la directory del pacchetto:

    mkdir dist
    copy .\build\Release\cpp-app.exe .\dist\
    
  3. Generare un certificato di sviluppo:

    winapp cert generate --if-exists skip
    
  4. Pacchetto e firma:

    winapp pack .\dist --cert .\devcert.pfx
    
  5. Installare il certificato (esegui come amministratore):

    winapp cert install .\devcert.pfx
    
  6. Installare ed eseguire:

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

Suggerimento

  • Firmare il MSIX con un certificato di firma del codice da una autorità di certificazione per la distribuzione in ambiente di produzione.
  • Microsoft Store firma MSIX per te, non è necessario firmare prima dell'invio.
  • Potrebbero essere necessari pacchetti MSIX separati per ogni architettura supportata (x64, Arm64).