Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
In diesem Handbuch wird veranschaulicht, wie Sie die winapp CLI mit einer C++-Anwendung verwenden, um mit Paketidentität zu debuggen und Ihre Anwendung als MSIX zu verpacken.
Die Paketidentität ist ein Kernkonzept im Windows app-Modell. Sie ermöglicht Ihrer Anwendung den Zugriff auf bestimmte Windows-APIs (z. B. Benachrichtigungen, Sicherheit, AI-APIs usw.), eine Benutzeroberfläche für die Neuinstallation/Deinstallation und vieles mehr.
Eine Standard-Ausführungsdatei (wie eine, die mit cmake --build erstellt wurde) hat keine Paketidentität. In diesem Handbuch wird gezeigt, wie Sie es zum Debuggen hinzufügen und dann für die Verteilung verpacken.
Voraussetzungen
Buildtools: Verwenden Sie eine Compilertoolkette, die von CMake unterstützt wird. In diesem Beispiel wird Visual Studio verwendet. Sie können die Community-Edition installieren (oder aktualisieren, falls sie bereits installiert ist):
winget install --id Microsoft.VisualStudio.Community --source winget --override "--add Microsoft.VisualStudio.Workload.NativeDesktop --includeRecommended --passive --wait"Neustart nach der Installation.
CMake: Installieren Sie CMake (oder aktualisieren Sie, falls bereits installiert):
winget install Kitware.CMake --source wingetwinapp CLI: Installieren Sie die
winappCli über winget (oder aktualisieren Sie, wenn bereits installiert):winget install Microsoft.winappcli --source winget
1. Erstellen einer neuen C++-App
Erstellen Sie zunächst eine einfache C++-Anwendung. Erstellen Sie ein neues Verzeichnis für Ihre project:
mkdir cpp-app
cd cpp-app
Erstellen Sie eine main.cpp Datei mit einem einfachen Programm "Hello, world!":
#include <iostream>
int main() {
std::cout << "Hello, world!" << std::endl;
return 0;
}
Erstellen Sie eine CMakeLists.txt Datei zum Konfigurieren des Builds:
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)
Erstellen Sie es und führen Sie es aus, um sicherzustellen, dass alles funktioniert:
cmake -B build
cmake --build build --config Debug
.\build\Debug\cpp-app.exe
Die Ausgabe sollte "Hallo, Welt!" lauten.
2. Aktualisieren von Code zum Überprüfen der Identität
Wir aktualisieren die App, um zu überprüfen, ob sie mit Paketidentität ausgeführt wird. Dadurch können wir überprüfen, ob die Identität in späteren Schritten ordnungsgemäß funktioniert. Wir verwenden die Windows-Runtime C++-API, um auf die Paket-APIs zuzugreifen.
Fügen Sie zunächst die folgende Zeile am Ende Ihres CMakeLists.txt hinzu, um eine Verknüpfung mit der Windows-App Modellbibliothek zu erstellen:
# Link Windows Runtime libraries
target_link_libraries(cpp-app PRIVATE WindowsApp.lib OneCoreUap.lib)
Ersetzen Sie als Nächstes den gesamten Inhalt von main.cpp durch den folgenden Code. Dieser Code versucht, die aktuelle Paketidentität mithilfe der Windows-Runtime-API abzurufen. Wenn er erfolgreich ist, wird der Paketfamilienname gedruckt. andernfalls wird "Nicht verpackt" gedruckt.
#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. Ohne Identität ausführen
Nun die App wie gewohnt neu erstellen und ausführen.
cmake --build build --config Debug
.\build\Debug\cpp-app.exe
"Sie sollten die Ausgabe 'Nicht verpackt' angezeigt sehen." Dadurch wird bestätigt, dass die standardmäßige ausführbare Datei ohne Paketidentität ausgeführt wird.
4. Projekt mit winapp CLI initialisieren
Der Befehl winapp init richtet alles ein, was Sie benötigen: App-Manifest, Ressourcen und optional Windows App SDK Header für die C++-Entwicklung.
Führen Sie den folgenden Befehl aus, und folgen Sie den Eingabeaufforderungen:
winapp init .
Wenn Sie dazu aufgefordert werden:
- Paketname: Drücken Sie die EINGABETASTE, um die Standardeinstellung zu akzeptieren (cpp-app)
- Publisher Name: Drücken Sie die EINGABETASTE, um die Standardeinstellung zu akzeptieren oder Ihren Namen einzugeben.
- Version: Drücken Sie die EINGABETASTE, um 1.0.0.0 zu akzeptieren.
- Einstiegspunkt: Drücken Sie die EINGABETASTE, um die Standardeinstellung zu übernehmen (cpp-app.exe)
- Setup-SDKs: Wählen Sie "Stable SDKs" aus, um Windows App SDK herunterzuladen und C++-Header zu generieren.
Dieser Befehl bewirkt Folgendes:
- Erstellen
Package.appxmanifest– das Manifest, das die Identität Ihrer App definiert - Erstellen eines Ordners
Assets– Symbole, die für die MSIX-Verpackung und die Store-Übermittlung erforderlich sind - Erstellen eines ordners
.winappmit Windows App SDK Headern und Bibliotheken - Erstellen Sie eine
winapp.yamlKonfigurationsdatei zum Festlegen von SDK-Versionen
Sie können Package.appxmanifest öffnen, um Eigenschaften wie den Anzeigenamen, den Herausgeber und die Funktionen weiter anzupassen.
Ausführungsalias hinzufügen (für Konsolen-Apps)
Mit einem Ausführungsalias können Benutzer Ihre App von jedem Terminal (z. B. cpp-app) ausführen. Es ermöglicht winapp run --with-alias auch während der Entwicklung, wodurch die Konsolenausgabe im aktuellen Terminal beibehalten wird, anstatt ein neues Fenster zu öffnen.
Sie können eins automatisch hinzufügen:
winapp manifest add-alias
Oder manuell: Öffnen Sie Package.appxmanifest und fügen Sie das uap5-Namespace dem <Package>-Tag hinzu, falls es fehlt, und fügen Sie dann die Erweiterung in <Applications><Application><Extensions>... hinzu:
<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. Debuggen mit Identität
Um Features zu testen, die Identität erfordern (z. B. Benachrichtigungen), ohne die App vollständig zu verpacken, können Sie verwenden winapp run. Dadurch wird ein loses Layoutpaket (genau wie eine echte MSIX-Installation) registriert und die App in einem Schritt gestartet. Für das Debuggen ist kein Zertifikat oder keine Signatur erforderlich.
Erstellen Sie die ausführbare Datei:
cmake --build build --config DebugAusführen mit Identität:
winapp run .\build\Debug --with-alias
Das --with-alias-Flag startet die App über seinen Ausführungsalias, sodass die Konsolenausgabe im aktuellen Terminal bleibt. Dazu benötigen wir das uap5:ExecutionAlias, das wir in Schritt 4 hinzugefügt haben.
Tipp
winapp run registriert außerdem das Paket auf Ihrem System. Aus diesem Grund wird msIX möglicherweise als "bereits installiert" angezeigt, wenn Sie versuchen, es später in Schritt 8 zu installieren. Verwenden Sie winapp unregister, um Entwicklungspakete zu bereinigen, wenn Sie fertig sind.
Nun sollte eine Ausgabe angezeigt werden, die ähnlich wie die folgende ist:
Package Family Name: cpp-app_12345abcde
Dadurch wird bestätigt, dass Ihre App mit einer gültigen Paketidentität ausgeführt wird!
Alternative: Sparse Paketidentität
Wenn Sie ein geringes Paketverhalten speziell benötigen (Identität ohne Kopieren von Dateien), können Sie stattdessen Folgendes verwenden create-debug-identity :
winapp create-debug-identity .\build\Debug\cpp-app.exe
.\build\Debug\cpp-app.exe
Tipp
Erweiterte Debugworkflows (Anfügen von Debuggern, IDE-Setup, Startdebugging) finden Sie im Debughandbuch.
6. Verwenden von Windows App SDK (Optional)
Wenn Sie während winapp init die SDKs eingerichtet haben, haben Sie jetzt Zugriff auf Windows App SDK Header im Ordner .winapp/include. Dadurch erhalten Sie Zugriff auf moderne Windows-APIs wie Benachrichtigungen, Fensterung, KI auf dem Gerät und vieles mehr. Wenn Sie nur die Paketidentität für die Verteilung benötigen, können Sie mit Schritt 7 fortfahren.
Fügen wir ein einfaches Beispiel hinzu, das die Windows-App Runtime-Version druckt.
Aktualisieren von CMakeLists.txt
Fügen Sie die folgende Zeile am Ende des CMakeLists.txt hinzu, um die Windows App SDK Kopfzeilen einzuschließen:
# Add Windows App SDK include directory
target_include_directories(cpp-app PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/.winapp/include)
Aktualisieren von main.cpp
Ersetzen Sie den gesamten Inhalt von main.cpp, um die Windows-App Runtime-API zu verwenden:
#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;
}
Erstellen und Ausführen
Erstellen Sie die Anwendung mit den Windows App SDK Headern neu:
cmake --build build --config Debug
winapp run .\build\Debug --with-alias
Nun sollte die Ausgabe wie folgt angezeigt werden:
Package Family Name: cpp-app_12345abcde
Windows App Runtime Version: 1.8-stable (1.8.0)
Das Verzeichnis .winapp/include enthält alle erforderlichen Header für Windows App SDK, einschließlich:
-
winrt/– WinRT C++-Projektionsheader für den Zugriff auf Windows-Runtime APIs -
Microsoft.UI.*.h– WinUI 3-Header für moderne UI-Komponenten -
MddBootstrap.h- Windows App SDK-Startvorgang -
WindowsAppSDK-VersionInfo.h- Versionsinformationen - Und viele weitere Windows App SDK Komponenten
Weitere Informationen zur erweiterten Windows App SDK-Verwendung finden Sie in der Dokumentation Windows App SDK.
7. Wiederherstellen von Kopfzeilen bei Bedarf
Der .winapp Ordner wird von winapp init automatisch zu .gitignore hinzugefügt, sodass er nicht in die Quellcodeverwaltung aufgenommen wird. Wenn andere Personen Ihr Projekt klonen, müssen sie diese Dateien vor dem Erstellen wiederherstellen.
Manuelle Einrichtung
Führen Sie diese beiden Befehle nach dem Klonen des Repositorys aus:
# 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
Anschließend können Sie normal erstellen und ausführen mit cmake -B build und cmake --build build --config Debug.
Automatisiertes Setup mit CMake
Alternativ können Sie dies automatisieren, indem Sie Ihre CMakeLists.txt-Setuplogik hinzufügen. Hier ist das vollständige CMakeLists.txt mit Automatisierung, korrekter Verknüpfung und minimalem C++20-Standard:
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)
Mit diesem Setup:
- Wenn jemand das Repository klont und
cmake -B buildausführt, wird winapp automatisch heruntergeladen, wenn es nicht im PATH gefunden wird. - Die Windows App SDK Kopfzeilen und das Zertifikat werden automatisch wiederhergestellt.
- Die Befehle werden nur einmal während der Konfiguration (nicht für jeden Build) ausgeführt, da sie überprüfen, ob die Dateien bereits vorhanden sind.
- Wenn die Befehle fehlschlagen, zeigt CMake eine Warnung mit Anweisungen an, um sie manuell auszuführen.
- Die heruntergeladene Winapp wird in
.winapp-tools/gespeichert (fügen Sie dies bei Bedarf zu.gitignorehinzu)
8. Paket mit MSIX
Sobald Sie bereit sind, Ihre App zu verteilen, können Sie sie mit demselben Manifest als MSIX verpacken. MSIX bietet saubere Installation/Deinstallation, automatische Updates und ein vertrauenswürdiges Installationserlebnis.
Vorbereiten des Paketverzeichnisses
Erstellen Sie zunächst Ihre Anwendung im Releasemodus, um eine optimale Leistung zu erzielen:
cmake --build build --config Release
Erstellen Sie dann ein Verzeichnis mit nur den notwendigen Dateien für die Verteilung und kopieren Sie Ihre ausführbare Datei:
mkdir dist
copy .\build\Release\cpp-app.exe .\dist\
Generieren eines Entwicklungszertifikats
MSIX-Pakete müssen signiert sein. Generieren Sie für lokale Tests ein selbstsigniertes Entwicklungszertifikat:
winapp cert generate --if-exists skip
Tipp
Der Herausgeber des Zertifikats muss mit dem Publisher in Ihrem Package.appxmanifest übereinstimmen. Der cert generate Befehl liest dies automatisch aus Ihrem Manifest.
Signieren und Packen
Jetzt können Sie Folgendes packen und signieren:
# package and sign the app with the generated certificate
winapp pack .\dist --cert .\devcert.pfx
Tipp
Der pack Befehl verwendet automatisch das Package.appxmanifest aus Ihrem aktuellen Verzeichnis und kopiert es vor dem Verpacken in den Zielordner. Die generierte .msix Datei befindet sich im aktuellen Verzeichnis.
Installieren des Zertifikats
Bevor Sie das MSIX-Paket installieren können, müssen Sie dem Entwicklungszertifikat auf Ihrem Computer vertrauen. Führen Sie diesen Befehl als Administrator aus (Sie müssen diesen Vorgang nur einmal pro Zertifikat ausführen):
winapp cert install .\devcert.pfx
Installieren und Ausführen
Tipp
Wenn Sie in Schritt 5 verwendet haben winapp run , ist das Paket möglicherweise bereits auf Ihrem System registriert. Verwenden Sie winapp unregister zunächst, um die Entwicklungsregistrierung zu entfernen, und installieren Sie dann das Release-Paket.
Der winapp pack Befehl generiert die MSIX-Datei in Ihrem Projektstammverzeichnis. Installieren Sie das Paket, indem Sie auf die generierte .msix Datei doppelklicken oder PowerShell verwenden:
Add-AppxPackage .\cpp-app_1.0.0.0_x64.msix
Tipp
Der MSIX-Dateiname enthält die Version und Architektur (z. B. cpp-app_1.0.0.0_arm64.msix). Überprüfen Sie Ihr Verzeichnis auf den genauen Dateinamen.
Jetzt können Sie Ihre App von praktisch überall im Terminal ausführen, indem Sie Folgendes eingeben:
cpp-app
Die Ausgabe "Paketfamilienname" sollte angezeigt werden, wobei bestätigt wird, dass sie installiert ist und mit Identität ausgeführt wird.
Tipp
Wenn Sie Ihre App neu verpacken müssen (z. B. nach Codeänderungen), erhöhen Sie den Wert von Version in Ihrem Package.appxmanifest, bevor Sie winapp pack erneut ausführen. Windows erfordert eine höhere Versionsnummer, um ein installiertes Paket zu aktualisieren.
Tipps
- Sobald Sie bereit für die Verteilung sind, können Sie Ihr MSIX mit einem Codesignaturzertifikat von einer Zertifizierungsstelle signieren, damit Ihre Benutzer kein selbstsigniertes Zertifikat installieren müssen.
- Der dienst Azure Trusted Signing ist eine hervorragende Möglichkeit, Ihre Zertifikate sicher zu verwalten und die Anmeldung in Ihre CI/CD-Pipeline zu integrieren.
- Der Microsoft Store signiert das MSIX für Sie, sodass Sie vor der Übermittlung nicht unterschreiben müssen.
- Möglicherweise müssen Sie mehrere MSIX-Pakete erstellen, eine für jede architektur, die Sie unterstützen (x64, Arm64). Konfigurieren Sie CMake mit den entsprechenden Generator- und Architekturflags.
Nächste Schritte
- Distribute via winget: Übermitteln Sie Ihren MSIX an das Windows Paket-Manager Community-Repository
-
Publish to the Microsoft Store: Verwenden Sie
winapp store, um Ihr Paket zu übermitteln. -
Set up CI/CD: Verwenden Sie die
setup-WinAppCliGitHub Action, um die Paketerstellung in Ihrer Pipeline zu automatisieren. - Explore Windows-APIs: Mit Paketidentität können Sie jetzt Benachrichtigungen, gerätenahe KI und andere identitätsabhängige APIs verwenden.
Windows developer