Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Questa guida illustra come utilizzare il CLI winapp con un'applicazione C++ per effettuare il debug con l'identità del pacchetto e impacchettare l'applicazione come MSIX.
L'identità del pacchetto è un concetto di base nel modello di Windows app. Consente all'applicazione di accedere a API di 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
Strumenti di compilazione: usare una toolchain del compilatore supportata da CMake. Questo esempio usa Visual Studio. È possibile installare l'edizione community con (o aggiornare se già installato):
winget install --id Microsoft.VisualStudio.Community --source winget --override "--add Microsoft.VisualStudio.Workload.NativeDesktop --includeRecommended --passive --wait"Riavviare dopo l'installazione.
CMake: installare CMake (o aggiornare se già installato):
winget install Kitware.CMake --source wingetCLI di winapp: installare la
winappCLI tramite winget (o aggiornare se già installata):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
L'output deve essere "Hello, world!"
2. Aggiornare il codice per controllare l'identità
Aggiorneremo l'app per verificare se è in esecuzione con l'identità del pacchetto. Ciò consentirà di verificare che l'identità funzioni correttamente nei passaggi successivi. Si userà l'API Windows Runtime C++ per accedere alle API del pacchetto.
Aggiungere prima di tutto la riga seguente alla fine del CMakeLists.txt per collegarsi alla libreria del modello di app di Windows:
# Link Windows Runtime libraries
target_link_libraries(cpp-app PRIVATE WindowsApp.lib OneCoreUap.lib)
Sostituire quindi l'intero contenuto di main.cpp con il codice seguente. Questo codice tenta di recuperare l'identità del pacchetto corrente usando l'API Windows Runtime. Se ha esito positivo, stampa il nome della famiglia di pacchetti; in caso contrario, stampa "Non in pacchetto".
#include <iostream>
#include <windows.h>
#include <appmodel.h>
int main() {
UINT32 length = 0;
LONG result = GetCurrentPackageFamilyName(&length, nullptr);
if (result == ERROR_INSUFFICIENT_BUFFER) {
// We have a package identity
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 {
// No package identity
std::cout << "Not packaged" << std::endl;
}
return 0;
}
3. Eseguire senza identità
A questo momento, ricompilare ed eseguire l'app come di consueto:
cmake --build build --config Debug
.\build\Debug\cpp-app.exe
Verrà visualizzato l'output "Non incluso nel pacchetto". Ciò conferma che l'eseguibile standard è in esecuzione senza alcuna identità del pacchetto.
4. Inizializzare il progetto con l'interfaccia della riga di comando di winapp
Il comando winapp init configura tutti gli elementi necessari in un unico passaggio: manifesto dell'app, asset e facoltativamente intestazioni SDK per app di Windows per lo sviluppo in C++.
Eseguire il comando seguente e seguire i prompt:
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 SDKs: Selezionare "SDK Stabili" per scaricare SDK per app di Windows e generare intestazioni C++
Questo comando consentirà di:
- Crea
Package.appxmanifest: manifesto che definisce l'identità dell'app - Crea
Assetscartella : icone necessarie per l'invio di pacchetti MSIX e dello Store - Creare una cartella
.winappcon le intestazioni e le librerie delle SDK per app di Windows - Creare un
winapp.yamlfile di configurazione per bloccare le versioni dell'SDK
È possibile aprire Package.appxmanifest per personalizzare ulteriormente le proprietà, ad esempio il nome visualizzato, l'editore e le funzionalità.
Aggiungere alias di esecuzione (per le app console)
Un alias di esecuzione consente agli utenti di eseguire l'app in base al nome da qualsiasi terminale ,ad esempio cpp-app. Consente inoltre winapp run --with-alias durante lo sviluppo, mantenendo l'output della console nel terminale corrente anziché aprire una nuova finestra.
È possibile aggiungerne una automaticamente:
winapp manifest add-alias
Oppure manualmente: aprire Package.appxmanifest e aggiungere lo spazio dei nomi uap5 al tag <Package> se manca, quindi aggiungere l'estensione all'interno del <Applications><Application><Extensions>....
<Package
...
xmlns:uap10="http://schemas.microsoft.com/appx/manifest/uap/windows10/10"
+ xmlns:uap5="http://schemas.microsoft.com/appx/manifest/uap/windows10/5"
IgnorableNamespaces="uap uap2 uap3 rescap desktop desktop6 uap10">
...
<Applications>
<Application ...>
...
+ <Extensions>
+ <uap5:Extension Category="windows.appExecutionAlias">
+ <uap5:AppExecutionAlias>
+ <uap5:ExecutionAlias Alias="cpp-app.exe" />
+ </uap5:AppExecutionAlias>
+ </uap5:Extension>
+ </Extensions>
</Application>
</Applications>
</Package>
5. Eseguire il debug con l'identità
Per testare le funzionalità che richiedono identità (ad esempio Notifiche) senza creare pacchetti completi dell'app, è possibile usare winapp run. Questo registra un pacchetto di layout libero (proprio come un'installazione MSIX reale) e avvia l'app in un unico passaggio. Non è necessario alcun certificato o firma per il debug.
Compilare il file eseguibile:
cmake --build build --config DebugEsegui con privilegi di identità:
winapp run .\build\Debug --with-alias
L'opzione --with-alias avvia l'app utilizzando il suo alias di esecuzione in modo che l'output della console rimanga nel terminale corrente. Questo richiede l'aggiunta uap5:ExecutionAlias nel passaggio 4.
Suggerimento
winapp run registra anche il pacchetto nel sistema. Ecco perché MSIX può essere visualizzato come "già installato" quando si tenta di installarlo più avanti nel passaggio 8. Usare winapp unregister per pulire i pacchetti di sviluppo al termine.
Verrà ora visualizzato un output simile al seguente:
Package Family Name: cpp-app_12345abcde
Ciò conferma che l'app è in esecuzione con un'identità del pacchetto valida.
Alternativa: Identità pacchetto sparse
Se è necessario un comportamento di pacchetto di tipo sparse in modo specifico (identità senza copiare file), è possibile usare create-debug-identity invece:
winapp create-debug-identity .\build\Debug\cpp-app.exe
.\build\Debug\cpp-app.exe
Suggerimento
Per i flussi di lavoro di debug avanzati (collegamento di debugger, installazione dell'IDE, debug di avvio), vedere la Guida al debug.
6. Uso di SDK per app di Windows (facoltativo)
Se si è scelto di configurare gli SDK durante winapp init, è ora possibile accedere alle intestazioni di SDK per app di Windows nella cartella .winapp/include. In questo modo è possibile accedere alle API di Windows moderne, ad esempio notifiche, finestre, intelligenza artificiale sul dispositivo e altro ancora. Se è sufficiente l'identità del pacchetto per la distribuzione, è possibile passare al passaggio 7.
Aggiungiamo un semplice esempio che stampa la versione di app di Windows Runtime.
Aggiornare CMakeLists.txt
Aggiungi la seguente riga alla fine del tuo CMakeLists.txt per includere le intestazioni di SDK per app di Windows:
# Add Windows App SDK include directory
target_include_directories(cpp-app PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/.winapp/include)
Aggiornare main.cpp
Sostituire tutto il contenuto di main.cpp utilizzando l'API di Runtime delle app di Windows.
#include <iostream>
#include <windows.h>
#include <appmodel.h>
#include <winrt/Microsoft.Windows.ApplicationModel.WindowsAppRuntime.h>
int main() {
// Initialize WinRT
winrt::init_apartment();
UINT32 length = 0;
LONG result = GetCurrentPackageFamilyName(&length, nullptr);
if (result == ERROR_INSUFFICIENT_BUFFER) {
// We have a package identity
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;
// Get Windows App Runtime version using the API
auto runtimeVersion = winrt::Microsoft::Windows::ApplicationModel::WindowsAppRuntime::RuntimeInfo::AsString();
std::wcout << L"Windows App Runtime Version: " << runtimeVersion.c_str() << std::endl;
} else {
std::wcout << L"Error retrieving Package Family Name" << std::endl;
}
} else {
std::cout << "Not packaged" << std::endl;
}
return 0;
}
Compilare ed eseguire
Ricompilare l'applicazione con le intestazioni dell'SDK per app di Windows.
cmake --build build --config Debug
winapp run .\build\Debug --with-alias
Verrà visualizzato un output simile al seguente:
Package Family Name: cpp-app_12345abcde
Windows App Runtime Version: 1.8-stable (1.8.0)
La directory .winapp/include contiene tutti i file di intestazione necessari per SDK per app di Windows, tra cui:
-
winrt/- Intestazioni di proiezione C++ WinRT per l'accesso alle API di Windows Runtime -
Microsoft.UI.*.h- Intestazioni WinUI 3 per i componenti moderni dell'interfaccia utente -
MddBootstrap.h- Inizializzazione del SDK per app di Windows -
WindowsAppSDK-VersionInfo.h- Informazioni sulla versione - E molti altri componenti SDK per app di Windows
Per un utilizzo SDK per app di Windows più avanzato, vedere la documentazione SDK per app di Windows.
7. Ripristinare le intestazioni quando necessario
La .winapp cartella viene aggiunta automaticamente a .gitignore da winapp init, quindi non verrà inclusa nel controllo del codice sorgente. Quando altri clonano il progetto, dovranno ripristinare questi file prima della compilazione.
Installazione manuale
Eseguire questi due comandi dopo la clonazione del repository:
# Restore Windows App SDK headers
winapp restore
# Generate development certificate (optional - only if planning to package the app and sideload)
winapp cert generate --if-exists skip
È quindi possibile compilare ed eseguire normalmente con cmake -B build e cmake --build build --config Debug.
Installazione automatica con CMake
In alternativa, è possibile automatizzare questa operazione aggiungendo la logica di configurazione a CMakeLists.txt. Ecco la versione completa CMakeLists.txt con automazione, collegamento corretto e standard C++20 minimo:
cmake_minimum_required(VERSION 3.20)
project(cpp-app)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# Download winapp CLI if not available in PATH
find_program(WINAPP_CLI winapp)
if(NOT WINAPP_CLI)
set(WINAPP_DIR "${CMAKE_CURRENT_SOURCE_DIR}/.winapp-tools")
set(WINAPP_CLI "${WINAPP_DIR}/winapp.exe")
if(NOT EXISTS "${WINAPP_CLI}")
message(STATUS "Downloading winapp CLI...")
# Determine architecture
if(CMAKE_SYSTEM_PROCESSOR MATCHES "ARM64|aarch64")
set(WINAPP_ARCH "arm64")
else()
set(WINAPP_ARCH "x64")
endif()
# Download and extract
set(WINAPP_ZIP "${CMAKE_CURRENT_BINARY_DIR}/winappcli.zip")
file(DOWNLOAD
"https://github.com/microsoft/WinAppCli/releases/latest/download/winappcli-${WINAPP_ARCH}.zip"
"${WINAPP_ZIP}"
SHOW_PROGRESS
)
file(ARCHIVE_EXTRACT INPUT "${WINAPP_ZIP}" DESTINATION "${WINAPP_DIR}")
file(REMOVE "${WINAPP_ZIP}")
message(STATUS "winapp CLI downloaded to ${WINAPP_DIR}")
endif()
endif()
# Automatically restore Windows App SDK headers and generate certificate if needed
# This runs once during CMake configuration, not on every build
if(NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/.winapp/include")
message(STATUS "Restoring Windows App SDK headers...")
execute_process(
COMMAND "${WINAPP_CLI}" restore
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
RESULT_VARIABLE RESTORE_RESULT
)
if(NOT RESTORE_RESULT EQUAL 0)
message(WARNING "Failed to restore Windows App SDK. Run 'winapp restore' manually.")
endif()
endif()
if(NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/devcert.pfx")
message(STATUS "Generating development certificate...")
execute_process(
COMMAND "${WINAPP_CLI}" cert generate --if-exists skip
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
RESULT_VARIABLE CERT_RESULT
)
if(NOT CERT_RESULT EQUAL 0)
message(WARNING "Failed to generate certificate. Run 'winapp cert generate' manually.")
endif()
endif()
add_executable(cpp-app main.cpp)
# Link Windows Runtime libraries
target_link_libraries(cpp-app PRIVATE WindowsApp.lib OneCoreUap.lib)
# Add Windows App SDK include directory
target_include_directories(cpp-app PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/.winapp/include)
Con questa configurazione:
- Quando un utente clona il repository ed esegue
cmake -B build, winapp viene scaricato automaticamente se non viene trovato in PATH - Le intestazioni e il certificato SDK per app di Windows vengono ripristinati automaticamente
- I comandi vengono eseguiti una sola volta durante la configurazione (non in ogni build) perché controllano se i file esistono già
- Se i comandi hanno esito negativo, CMake visualizza un avviso con le istruzioni per eseguirle manualmente
- L'app winapp scaricata viene archiviata in
.winapp-tools/(aggiungerla a.gitignore, se necessario)
8. Pacchetto con MSIX
Quando si è pronti per distribuire l'app, è possibile crearne il pacchetto come MSIX usando lo stesso manifesto. MSIX offre installazione/disinstallazione pulita, aggiornamenti automatici e un'esperienza di installazione attendibile.
Preparare la directory del pacchetto
Prima di tutto, compilare l'applicazione in modalità di rilascio per ottenere prestazioni ottimali:
cmake --build build --config Release
Creare quindi una directory con solo i file necessari per la distribuzione e copiare il file eseguibile della versione:
mkdir dist
copy .\build\Release\cpp-app.exe .\dist\
Generare un certificato di sviluppo
I pacchetti MSIX devono essere firmati. Per i test locali, generare un certificato di sviluppo autofirmato:
winapp cert generate --if-exists skip
Suggerimento
L'emittente del certificato deve corrispondere al Publisher nel Package.appxmanifest. Il cert generate comando legge automaticamente il file dal manifesto.
Firma e pacchetto
È ora possibile creare un pacchetto e firmare:
# package and sign the app with the generated certificate
winapp pack .\dist --cert .\devcert.pfx
Suggerimento
Il pack comando usa automaticamente la Package.appxmanifest dalla directory corrente e la copia nella cartella di destinazione prima dell'impacchettamento. Il file generato .msix si troverà nella directory corrente.
Installare il certificato
Prima di poter installare il pacchetto MSIX, è necessario considerare attendibile il certificato di sviluppo nel computer. Eseguire questo comando come amministratore (è necessario eseguire questa operazione una sola volta per ogni certificato):
winapp cert install .\devcert.pfx
Installare ed eseguire
Suggerimento
Se è stato usato winapp run nel passaggio 5, il pacchetto potrebbe essere già registrato nel sistema. Usare winapp unregister prima di tutto per rimuovere la registrazione di sviluppo, quindi installare il pacchetto di versione.
Il winapp pack comando genera il file MSIX nella directory radice del progetto. Installare il pacchetto facendo doppio clic sul file generato .msix o usando PowerShell:
Add-AppxPackage .\cpp-app_1.0.0.0_x64.msix
Suggerimento
Il nome file MSIX include la versione e l'architettura (ad esempio, cpp-app_1.0.0.0_arm64.msix). Controlla la directory per trovare il nome file esatto.
È ora possibile eseguire l'app da qualsiasi punto del terminale digitando:
cpp-app
Verrà visualizzato l'output "Package Family Name", che conferma che è installato e in esecuzione con l'identità.
Suggerimento
Se è necessario ricreare il pacchetto dell'app (ad esempio, dopo modifiche al codice), incrementare il valore in Version nel Package.appxmanifest prima di eseguire nuovamente winapp pack. Windows richiede un numero di versione superiore per aggiornare un pacchetto installato.
Tips
- Quando si è pronti per la distribuzione, è possibile firmare MSIX con un certificato di firma del codice da un'autorità di certificazione in modo che gli utenti non devono installare un certificato autofirmato.
- Il servizio Firma attendibile di Azure è un ottimo modo per gestire i certificati in modo sicuro e integrare l'accesso alla pipeline CI/CD.
- Il Microsoft Store firmerà MSIX per te, non è necessario firmare prima dell'invio.
- Potrebbe essere necessario creare più pacchetti MSIX, uno per ogni architettura supportata (x64, Arm64). Configurare CMake con il generatore e i flag di architettura appropriati.
Operazioni successive
- Distribute tramite winget: Presenta il tuo MSIX al Windows Gestione pacchetti Community Repository
-
Pubblica al Microsoft Store: Utilizzare
winapp storeper inviare il pacchetto -
Configura CI/CD: utilizza l'azione
setup-WinAppCliGitHub per automatizzare il confezionamento nella pipeline - API Explore Windows: Con l'identità del pacchetto, è ora possibile usare Notifications, on-device AI e altre API dipendenti da identity