Documentation et utilisation de l’interface CLI

Version

Imprimez la version winapp installée avec --version ou sa forme -Vcourte :

winapp -V

Minuscules -v est la forme courte des --verbose commandes (par exemple, winapp restore -v).

Achèvement de l’interpréteur de commande

Activez la saisie semi-automatique de tabulation pour les commandes, les options et les valeurs. Consultez le guide de saisie semi-automatique de Shell pour obtenir des instructions de configuration.

# Quick setup for PowerShell (permanent — add to profile)
winapp complete --setup powershell >> $PROFILE

# Or try it in the current session only
winapp complete --setup powershell | Out-String | Invoke-Expression

Init

Initialisez un répertoire avec le Kit de développement logiciel (SDK) Windows, SDK d'application Windows et les ressources requises pour le développement Windows moderne.

winapp init [base-directory] [options]

Arguments :

  • base-directory - Répertoire de base/racine de l’application/espace de travail (par défaut : répertoire actif)

Options :

  • --config-dir <path> - Répertoire pour lire/stocker la configuration (valeur par défaut : répertoire du projet sélectionné ou répertoire actif si aucun projet n’est détecté)
  • --setup-sdks - Mode d’installation du Kit de développement logiciel (SDK) : « stable » (valeur par défaut), « préversion », « expérimental » ou « none » (ignorer l’installation du SDK)
  • --ignore-config, - --no-config N’utilisez pas de fichier de configuration pour la gestion des versions
  • --no-gitignore - Ne mettez pas à jour le fichier .gitignore
  • --use-defaults, - --no-prompt Ne pas inviter et utiliser la valeur par défaut de toutes les invites
  • --config-only - Gérer uniquement les opérations de fichier de configuration, ignorer l’installation du package
  • --exe <path> - Chemin d’accès à l’exécutable de l’application. Exige --sparse. Génère un manifeste éparse d’identité uniquement pour l’exe au lieu d’une configuration complète de package/SDK.
  • --sparse - Générer un manifeste d’identité partiellement alloué (appxmanifest.xml) pour un exe de bureau existant. Ignore l’installation du Kit de développement logiciel (SDK)/package. Utiliser avec --exe.
  • --name <name> - Remplacer le nom du package (éparse uniquement ; valeur par défaut : déduit de l’exe)
  • --publisher <CN> - Remplacer le CN de l’éditeur (partiellement alloué uniquement ; valeur par défaut : déduit du nom de la société de l’exe)
  • --output-dir <path> - Répertoire pour écrire le manifeste épars et Assets/ (éparse uniquement ; par défaut : un sparse/ dossier dans le répertoire actif)
  • --force - Remplacer un existant appxmanifest.xml dans le répertoire cible (éparse uniquement). Sans cela, l’init échoue au lieu de remplacer un manifeste/des ressources existants.
  • --add-js-bindings (npm uniquement) - Ajouter winapp.jsBindings à package.json et générer des liaisons JS/TypeScript, sans inviter (incompatible avec --setup-sdks none)

Résultat :

  • Crée un winapp.yaml fichier de configuration (uniquement lorsque les packages du Kit de développement logiciel (SDK) sont gérés ; ignorés avec --setup-sdks none)
  • Télécharge les packages du Kit de développement logiciel (SDK) et de SDK d'application Windows
  • Utilise la version SDK d'application Windows la plus récente dans le canal sélectionné--setup-sdks. Si cette version est toujours publiée et que certains de ses packages ne sont pas encore disponibles, init utilise la version précédente à la place et imprime une note indiquant ainsi. Pour passer à la nouvelle version ultérieurement, exécutez winapp updateou pour un projet .NET. dotnet add package Microsoft.WindowsAppSDK --version <new version>
  • Génère des en-têtes C++/WinRT et des fichiers binaires
  • Crée Package.appxmanifest
  • Configure les outils de génération et active le mode développeur
  • Met à jour .gitignore pour exclure les fichiers générés
  • Stocke les fichiers partageables dans le répertoire global du cache
  • Génère des liaisons JS pour les API SDK d'application Windows lorsqu’elles sont activées (npm uniquement)

Détection automatique des projets :

Lorsqu’il init est exécuté sans argument de répertoire, il effectue une recherche étendue de l’arborescence de répertoires active pour rechercher des projets compatibles (jusqu’à 10). Types de projets pris en charge :

  • Tauri — tauri.conf.json trouvé un niveau sous le répertoire
  • Electron — package.json avec electron des dépendances ou devDependencies
  • Flutter — pubspec.yaml à la racine du projet
  • .NET — .csproj à la racine du projet
  • Rust — Cargo.toml à la racine du projet
  • C++ : CMakeLists.txt à la racine du projet

La recherche ignore les répertoires couramment ignorés (node_modules, bin, obj, .git, etc.). Lorsqu’un projet compatible est trouvé, les sous-répertoires ci-dessous ne sont pas recherchés.

  • Si un argument de répertoire est fourni (par exemple, winapp init . ou winapp init path/to/project), la recherche est ignorée et init vérifie uniquement ce répertoire pour un projet compatible
  • Si --use-defaults (ou --no-prompt) est défini sans argument de répertoire, init ignore la recherche et initialise le répertoire actif de manière non interactive, en premier lieu si aucun type de projet connu n’est détecté (par exemple, winapp init --use-defaults)
  • Dans les environnements non interactifs (stdin redirigé, CI, entrée redirigée), init utilise --use-defaults automatiquement le comportement et émet un avertissement : Non-interactive environment detected. Using default values.
  • Si le répertoire actif est un projet compatible, init procédez immédiatement
  • Si exactement un projet est trouvé ailleurs, vous êtes invité à confirmer
  • Si plusieurs projets sont trouvés, vous pouvez sélectionner celui à initialiser : le répertoire actif est toujours disponible en tant qu’option de secours
  • Si aucun projet n’est trouvé, vous êtes averti et vous avez demandé s’il faut continuer de toute façon
  • Si la recherche atteint la limite de 10 projets, un avertissement suggère de fournir un argument d’annuaire

Flux de projet de .NET automatique :

Lorsqu’un fichier .csproj se trouve dans le répertoire cible, init utilise un flux simplifié spécifique aux .NET :

  • Valide et met à jour le TargetFramework sur un TFM compatible avec Windows (par exemple, net10.0-windows10.0.26100.0)
  • Ajoute Microsoft.WindowsAppSDK et Microsoft.Windows.SDK.BuildTools en tant qu’entrées NuGet PackageReference directement dans le .csproj
  • Génère Package.appxmanifest, des ressources, et un certificat de développement
  • Ne crée pas ou ne télécharge winapp.yaml de projections C++ (utilisation dotnet restore pour les packages NuGet)

Mode d’identité partiellement alloué (--exe + --sparse) :

Génère un manifeste de package éparse d’identité uniquement pour un exécutable de bureau existant , la première étape du flux de travail d’empaquetage partiellement alloué. Contrairement au flux complet init , cela ignore toutes les installations du SDK/package (les packages d’identité partiellement alloués n’ont pas de dépendances du SDK) et génère uniquement un manifeste et des ressources d’espace réservé.

  • Déduit le nom du package, l’éditeur, la description et la version de l’exe via FileVersionInfo (remplacer par --name, --publisherou interactivement)
  • Écrit appxmanifest.xml (avec le nom d’exe remplacé dans Executable) plus un Assets/ dossier dans un sparse/ dossier dans le répertoire actif (ou --output-dir)
  • Utilise --use-defaults/--no-prompt pour ignorer les invites de remplacement interactives (compatibles CI)
  • --exe sans --sparse erreur

Les ressources sont externes. L’éparse .msix est uniquement l’identité : les éléments Assets/ générés sont résolus à partir du répertoire d’installation de l’application (l’emplacement du contenu externe) au moment de l’exécution, et non regroupés dans le .msixfichier . Déployez-les en même temps que votre application.

Étapes suivantes après winapp init --exe <exe> --sparse: winapp pack <appxmanifest.xml> pour générer l’identité .msix, puis winapp embed-identity <exe>. Consultez le Guide d’empaquetage partiellement alloué pour obtenir la procédure pas à pas complète.

Exemples :

# Initialize current directory
winapp init

# Initialize with experimental packages
winapp init --setup-sdks experimental

# Initialize specific directory without prompts
winapp init ./my-project --use-defaults

# Initialize a .NET project (auto-detected from .csproj)
cd my-dotnet-app
winapp init

# Generate a sparse identity manifest for an existing exe (no SDK install)
winapp init --exe ./bin/Release/net8.0-windows/MyApp.exe --sparse --use-defaults

Conseil : Installer des kits SDK après l’installation initiale

Si vous avez exécuté init avec --setup-sdks none (ou ignoré l’installation du Kit de développement logiciel (SDK) et que vous avez besoin ultérieurement des kits SDK :

# Re-run init to install SDKs - preserves existing files (manifest, etc.)
winapp init . --use-defaults --setup-sdks stable

Utilisez --setup-sdks preview ou --setup-sdks experimental pour les versions préliminaires/expérimentales du Kit de développement logiciel (SDK) expérimental.


Nouveau

Créez une application WinUI à partir d’un modèle de SDK d'application Windows dotnet new officiel. Interactive par défaut ; utilise automatiquement les valeurs par défaut dans les environnements non interactifs.

winapp new [options]

Options :

  • -t, --template <short-name>- Nom court du modèle (par exemplewinui, winui-navviewwinui-libwinui-mvvm, , winui-unittestou un modèle de réacteur expérimental tel que reactor ou ).reactor-mvu Validé par rapport au pack installé au moment de l’exécution ; s’exécute winapp new --list pour voir tout. Valeur par défaut : winui (application XAML vide).
  • -n, --name <name> - Nom de la nouvelle application/projet (par défaut : dérivé de --output, sinon WinUIApp)
  • -o, --output <path> - Répertoire dans lequel créer l’application (par défaut : ./<name>)
  • --use-defaults, - --no-prompt Ne pas inviter ; utilisez les valeurs par défaut (modèle vide, nom et conservez le pack de --output/--namemodèles installé plutôt que de le mettre à jour)
  • --force - Structurer même si le répertoire de sortie contient déjà des fichiers
  • --template-version <latest|installed|version> - Version du pack de modèles WinUI : latest les mises à jour du pack publié le plus récent sans invite (un pack installé qui est déjà plus récent, tel qu’une build de préversion locale, est conservé ; échoue si le flux ne peut pas être vérifié), installed conserve ce qui est déjà téléchargé (aucun réseau) ou épingle une version explicite telle que 1.2.3. Valeur par défaut : installez la dernière fois qu’aucun pack n’est présent, sinon invitez à mettre à jour un pack obsolète (conservé as-is sous --use-defaults).
  • --list - Répertorier les modèles WinUI disponibles et quitter (installe d’abord le dernier pack si aucun n’est installé)
  • --json - Mettre en forme la sortie en tant que JSON

Modèles:

Le pack fournit deux styles d’application WinUI. Les modèles XAML définissent l’interface utilisateur dans le balisage avec un code-behind C#. Les modèles de réacteur sont purs C# sans XAML, à l’aide d’un modèle MVU (Model-View-Update). La liste des modèles est lue en direct à partir du pack installé, de sorte qu’elle reflète toujours la version que vous avez , exécutée winapp new --list pour voir l’ensemble actuel. Le sélecteur interactif et --list affiche d’abord les modèles WinUI, puis tous les autres, chaque groupe par ordre alphabétique. Modèles courants :

Nom court Description
winui Application XAML vide minimale (empaquetage MSIX)
winui-navview Application de démarrage NavigationView XAML
winui-tabview Application de démarrage TabView XAML
winui-mvvm Application MVVM XAML (CommunityToolkit.Mvvm)
winui-lib Bibliothèque de classes WinUI 3
winui-unittest Application MSTest empaquetée ; les tests s’exécutent quand il est lancé
reactor Expérimental. Application Reactor vide — C#pur, pas DE XAML
reactor-mvu Expérimental. Application Reactor illustrant le modèle MVU
reactor-navview Expérimental. Application de démarrage Reactor NavigationView
reactor-tabview Expérimental. Application de démarrage De Reactor TabView

Les modèles de réacteur sont expérimentaux. Ils référencent les packages de préversion Microsoft.UI.Reactor , dont les API peuvent changer ou être supprimées dans une version ultérieure. winapp new les marque (expérimental) dans --list et dans le sélecteur interactif, se définit "Experimental": true dans --jsonet imprime un avertissement après la génération de modèles automatique. Ils ne sont jamais choisis comme modèle par défaut. Reactor nécessite également le sdk .NET 10 ou une version ultérieure ; sur un sdk winapp new plus ancien échoue avant avec la version dont il a besoin plutôt que de générer un projet que vous ne pouvez pas générer.

Le nom court canonique de chaque modèle est la première liste d’alias dotnet new pour celui-ci ; tout alias listé (par exemple winui3, , wasdk-single, winui-reactor) est également accepté. Si un autre pack de modèles installé inscrit le même nom court (par exemple, reactor à partir de ), Microsoft.UI.Reactor.Templateswinapp new crée toujours le modèle du pack WinUI à l'aide de l'un de ses autres alias. Si un autre pack inscrit chaque alias dont dispose le modèle, winapp new arrête et nomme ce pack. Supprimez-le et dotnet new uninstall <package> réexécutez-le. Lors de l’exécution à l’intérieur d’un projet WinUI existant, dotnet new affiche également des modèles d’éléments (par exemple, une page vide), qui winapp new s’ajoute au projet actuel plutôt que de créer un nouveau projet.

Contrôle de version du pack de modèles :

winapp new n’épingle plus une version spécifique du pack de modèles. Si aucun pack n’est installé, il installe la dernière version. Si un pack plus ancien est déjà installé, il vérifie le flux et, lorsqu’il en existe un plus récent, vous invite à mettre à jour , sauf dans les exécutions non interactives/--use-defaults qui conservent le pack installé. Utilisez --template-version latest pour toujours prendre le plus récent sans demander (il ne remplace jamais un pack installé par un pack plus ancien et échoue si le flux ne peut pas être vérifié) ou --template-version installed pour toujours utiliser le pack téléchargé sans vérification réseau. Le passage d’une version explicite (par exemple --template-version 1.2.3) installe toujours exactement cette version , réinstallant même lorsqu’un pack plus récent est déjà présent, de sorte que la génération de modèles est reproductible sur les ordinateurs.

Une première exécution peut prendre plus de temps : L’installation ou la mise à jour du pack de modèles ou la restauration des packages NuGet manquants SDK d'application Windows utilisés par le modèle sélectionné peuvent nécessiter des téléchargements supplémentaires. Cela peut également se produire après la publication d’une nouvelle version de SDK d'application Windows. Si la génération de modèles automatique est toujours en cours d’exécution après 10 secondes, winapp new met à jour son message d’état pour indiquer que les packages peuvent être téléchargés ou restaurés.

Résultat :

  • Vérifie que le KIT DE DÉVELOPPEMENT logiciel (SDK) .NET est installé (échoue rapidement avec des conseils en cas d’absence — winapp n’installe pas les chaînes d’outils)
  • Installe ou met à jour le pack de modèles WinUI officiel (Microsoft.WindowsAppSDK.WinUI.CSharp.Templates) à la demande
  • Énumère les modèles disponibles à partir du pack installé et délègue la génération de modèles à dotnet new <short-name>

Les modèles d’application WinUI incluent déjà Windows empaquetage et identité (Package.appxmanifest), donc aucune étape distincte winapp init n’est requise. Pour les modèles d’application, utilisez winapp run cette option pour générer et lancer l’application. Le winui-lib modèle produit une bibliothèque de classes à référencer à partir d’un projet d’application (il n’a pas de manifeste d’application). Le winui-unittest modèle est une application MSTest empaquetée dont les tests s’exécutent lorsque l’application est lancée (winapp run) et non via dotnet test. winapp newscaffolds par rapport à l'infrastructure cible de votre kit de développement logiciel (SDK) installé .NET et imprime l'étape suivante appropriée pour le modèle que vous choisissez.

Transmettez l’indicateur global --verbose (-v) pour faire écho à chaque appel sous-jacent dotnet (requête pack, vérification de mise à jour, installation, dotnet new liststructure) ainsi que sa sortie complète , utile pour diagnostiquer les problèmes de modèle-pack ou de génération de modèles.

Exemples :

# Interactive: pick a template, then a name (output defaults to ./<name>)
winapp new

# List the available templates without scaffolding
winapp new --list

# One-shot with a specific template
winapp new --name MyApp --template winui-navview

# Experimental Reactor app (pure C#, no XAML) — requires the .NET 10 SDK
winapp new --name MyApp --template reactor-mvu

# Always use the newest template pack, no prompts
winapp new --name MyApp --template-version latest --use-defaults

# Show the underlying dotnet commands and their output
winapp new --name MyApp --verbose

# Non-interactive (agent) with machine-readable output
winapp new --use-defaults --name MyApp --json

restore

Restaurez des packages et régénérez les fichiers en fonction de la configuration existante winapp.yaml .

winapp restore [base-directory] [options]

Arguments :

  • base-directory - Répertoire à restaurer (par défaut : répertoire actif). Sélectionne également l’emplacement winapp.yaml et nuget.config la lecture, sauf si --config-dir elle est remplacée.

Options :

  • --config-dir <path> - Répertoire contenant winapp.yaml (par défaut : base-directory)

Résultat :

  • Lit la configuration existante winapp.yaml
  • Téléchargements/mises à jour des packages sdk vers des versions spécifiées
  • Régénère les en-têtes C++/WinRT et les fichiers binaires
  • Stocke les fichiers partageables dans le répertoire global du cache

Note

Pour .NET projets, il n’existe aucune winapp.yaml version du KIT DE développement logiciel (SDK) en tant qu’entrées PackageReference.csproj . Par conséquentwinapp restore, elle s’exécute dotnet restore pour vous.

Exemples :

# Restore from winapp.yaml in current directory
winapp restore

# Restore a specific project directory (reads ./my-project/winapp.yaml)
winapp restore ./my-project

Flux NuGet personnalisés et privés :

winapp init, restoreet update téléchargez le sdk Windows et les packages SDK d'application Windows via NuGet, en respectant votre hiérarchie standardnuget.config. Flux privés et miroirs, informations d’identification de flux (y compris les fournisseurs d’informations d’identification) et un travail personnalisé globalPackagesFolder comme ils le font pour dotnet restore. Pour restaurer exclusivement à partir de votre propre miroir, <clear /> les sources héritées et ajoutez simplement le vôtre :

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <packageSources>
    <clear />
    <add key="contoso" value="https://pkgs.dev.azure.com/contoso/_packaging/winsdk-mirror/nuget/v3/index.json" />
  </packageSources>
</configuration>

Note

Pour les projets natifs, winapp résout nuget.config à partir du répertoire sur lequel il fonctionne : l’argumentrestoreinit/de répertoire, --config-dir lorsqu’il est donné, sinon le répertoire actif. Pour .NET projets, les sources proviennent plutôt de la hiérarchie du nuget.config projet, car c'est ce qui dotnet add package et dotnet restore est utilisé, donc placez la configuration d'un flux privé dans le répertoire du projet ou un ancêtre. En --config-dir dehors de cette hiérarchie, elle est signalée et ignorée au lieu de sélectionner en mode silencieux les versions que le projet ne peut pas restaurer. Exécutez ces commandes uniquement sur les répertoires auxquels vous faites confiance, la même prudence qui s’applique à dotnet restore. Lorsque plusieurs sources sont configurées, utilisez le mappage de source de package pour épingler chaque package à un flux.


update

Mettez à jour les packages vers leurs dernières versions et mettez à jour le fichier de configuration.

winapp update [options]

Options :

  • --setup-sdks <stable|preview|experimental|none>- Mode d’installation du Kit de développement logiciel (SDK) : stable (par défaut), previewou experimentalnone (ignorer l’installation du Kit de développement logiciel (SDK)

Résultat :

  • Lit la configuration existante winapp.yaml dans le répertoire actif
  • Met à jour tous les packages vers leurs dernières versions disponibles. Une version SDK d'application Windows qui est toujours publiée est ignorée jusqu’à ce que tous ses packages soient disponibles et update imprime une note nommant la version utilisée à la place. Réexécutez winapp update plus tard pour passer à la nouvelle version.
  • Met à jour le fichier avec les winapp.yaml nouveaux numéros de version
  • Régénère les en-têtes C++/WinRT et les fichiers binaires

Exemples :

# Update packages to latest versions
winapp update

# Update including experimental packages
winapp update --setup-sdks experimental

pack

Créez des packages MSIX à partir d’un projet ou de répertoires d’applications préparés. Nécessite un fichier manifeste (Package.appxmanifest préféré, appxmanifest.xml également pris en charge) à présenter dans le répertoire cible, dans le répertoire actif ou passé avec l’option --manifest . (exécuter init ou manifest generate créer un manifeste)

Transmettez un seul .csproj pour générer le projet et empaqueter sa sortie en une seule étape (mode projet, consultez Empaquetage d’un projet directement ci-dessous). Transmettez plusieurs dossiers d’entrée pour créer une .msixbundle distribution multi-architecture (consultez bundles multi-architecture ci-dessous ).

winapp pack <input-folder> [input-folder...] [options]

Arguments :

  • input-folder - Un seul .csproj pour générer et empaqueter (mode projet), ou un ou plusieurs répertoires contenant les fichiers d’application à empaqueter. Transmettez plusieurs dossiers (par exemple) ./publish/x64 ./publish/arm64pour créer un bundle MSIX. Pour les packages d’identité partiellement alloués, transmettez un fichier partiellement alloué appxmanifest.xml directement au lieu d’un dossier (voir Packages d’identité partiellement alloués ci-dessous).

Options :

  • --output <filename> - Nom du fichier de sortie. Pour les packages uniques : <name>_<version>_<arch>.msix (revenir à <name>_<version>.msix, <name>_<arch>.msixou <name>.msix). Pour les bundles : <name>_<version>_<arch1>_<arch2>.msixbundle.
  • --name <name> - Nom du package (valeur par défaut : à partir du manifeste)
  • --manifest <path> - Chemin d’accès au fichier manifeste (Package.appxmanifest préféré, appxmanifest.xml également pris en charge ; par défaut : détection automatique)
  • --cert <path> - Chemin d’accès au certificat de signature (active la signature automatique)
  • --cert-password <password> - Mot de passe du certificat (par défaut : « mot de passe »)
  • --generate-cert - Générer un nouveau certificat de développement
  • --no-sign - Fournissez le package non signé, en remplaçant toute configuration de signature de projet (par exemple, pour la soumission du Windows Store ou un pipeline de signature externe). Impossible de combiner avec --cert ou --generate-cert.
  • --install-cert - Installer un certificat sur l’ordinateur
  • --publisher <name>- Publisher pour la génération de certificat. Accepte un nom unique X.500 complet ou un nom nu (automatiquement encapsulé en tant que CN=<name>)
  • --self-contained - Runtime SDK d'application Windows groupé
  • --skip-pri - Ignorer la génération de fichiers PRI
  • --executable <path> - Chemin d’accès à l’exécutable par rapport au dossier d’entrée (également --exe). Permet de résoudre les espaces réservés $targetnametoken$ dans le manifeste.

Project options en mode (exiger une .csproj entrée ; rejetées pour les entrées dossier/bundle/manifeste) :

  • --configuration <name> (-c) - Configuration de build (par défaut : Release)
  • --arch <arch> - Architecture cible : x64, arm64ou x86 (par défaut : architecture de processus actuelle)
  • --framework <tfm> (-f) - Moniker de framework cible pour les projets multi-ciblés
  • --no-build - Empaqueter la sortie de build existante sans regénérer
  • --no-restore - Ignorer la restauration du projet avant la génération
  • --property <name=value> (-p) - Propriété MSBuild, transférée à la génération et à l’évaluation (reproductible)

Remarque : Pour un mode projet WinUI / EnableMsixTooling.csproj (MSIX-tooling), l'SDK d'application Windows possède le manifeste, le point d'entrée et la génération PRI. Par conséquent--manifest--executable, et --skip-pri sont rejetés , configurez, le <AppxManifest>point d'entrée du projet et sa build de ressources dans le projet lui-même. Ces trois options s’appliquent toujours aux entrées de dossier et au mode de projet générique (non-MSIX-tooling). .csproj

Résultat :

  • Valide et traite les fichiers Package.appxmanifest
  • Résout les jetons $placeholder$ dans le manifeste (voir espaces réservés du manifeste ci-dessous)
  • Garantit les dépendances d’infrastructure appropriées
  • Met à jour des manifestes parallèles avec des enregistrements
  • Détecte et regroupe automatiquement tous les fichiers non-image référencés dans le manifeste (par exemple, AppExtension manifest.json, fichiers config) à partir du répertoire manifeste ou du dossier d’entrée s’ils sont manquants dans la préproduction
  • Découvre automatiquement les composants WinRT tiers et inscrit leurs classes activables (voir découverte de composants WinRT ci-dessous)
  • Gère le déploiement WinAppSDK autonome
  • Signe le paquet si le certificat est fourni

Empaquetage direct d’un projet

Lorsque l’entrée est unique .csproj, winapp pack génère le projet (à l’aide des options ci-dessus) et empaquet la sortie résultante, il n’est pas nécessaire de générer séparément ou de localiser d’abord le dossier de sortie. Ce mode de projet reflète winapp runle mode projet.

# Build MyApp in Release for arm64 and package + sign it in one step
winapp pack ./MyApp.csproj -c Release --arch arm64 --cert ./devcert.pfx

# Package an existing build output without rebuilding
winapp pack ./MyApp.csproj --no-build

# Select the target architecture with an exact RID instead of --arch
winapp pack ./MyApp.csproj -p RuntimeIdentifier=win-x64

L’architecture cible provient ou d’un --archseul -p RuntimeIdentifier=<rid> quand vous ne passez --arch pas (le RID exact est conservé et pilote la build). Passer les deux --arch et -p RuntimeIdentifier est un conflit et est rejeté.

Le projet doit générer en tant qu’application empaquetée (EnableMsixTooling=true avec un Package.appxmanifest) ; un projet qui s’génère en tant qu’application non empaquetée (WindowsPackageType=None) n’a pas de manifeste MSIX pour empaqueter et winapp pack signale une erreur actionnable. Les entrées de dossier, d’offre groupée et de manifeste partiellement alloué sont inchangées.

Project mode produit un seul .msix ou un mode architecture uniquement .msixbundle (voir offres groupées multi-architecture). Il ne produit pas d’archives de chargement de magasin ou de bundles de fractionnement de ressources (langage/mise à l’échelle) : un objet explicite -p UapAppxPackageBuildMode=StoreUpload ou -p AppxBundleAutoResourcePackageQualifiers=... rejeté avec une note pour exécuter la commande d’empaquetage native du KIT de développement logiciel (SDK) directement pour ces flux.

Packages d’identité partiellement alloués

Lorsque l’entrée est un fichier partiellement alloué appxmanifest.xml (une déclaration <uap10:AllowExternalContent>true</uap10:AllowExternalContent> sous <Properties>) plutôt qu’un dossier, génère une identité uniquement.msix , winapp pack il empaque uniquement le manifeste, sans fichiers binaires ou ressources d’application. Il s’agit de l’étape 2 du flux de travail d’empaquetage épars.

# Build a signed identity package from a sparse manifest
winapp pack ./sparse/appxmanifest.xml --cert ./devcert.pfx
  • La sortie est par défaut <PackageName>.identity.msix dans le répertoire actif (remplacer par --output).
  • La signature se produit uniquement lorsque --cert (ou --generate-cert) est fournie.
  • Si vous transmettez au lieu de cela un dossier dont le manifeste déclare AllowExternalContent, le comportement d’empaquetage de dossiers existant s’applique, mais winapp pack avertit s’il trouve des ressources (.ico//.png.jpg) ou des fichiers binaires (.exe.dll//.so) pour les packages partiellement alloués qui appartiennent à l’emplacement externe, et non à l’intérieur du ..msix

Après avoir empaquetage, exécutez et inscrivez winapp embed-identity <exe> le package dans votre programme d’installation avec Add-AppxPackage -Path <msix> -ExternalLocation <install-dir>. Consultez le Guide d’empaquetage partiellement alloué.

Découverte de composants WinRT

Lors de l’empaquetage, winapp pack analyse automatiquement les packages NuGet définis dans les winapp.yaml*.csproj composants WinRT tiers (par exemple, Win2D). Il analyse les .winmd fichiers pour extraire les noms de classes activables et localiser leurs DLL d’implémentation. Les entrées découvertes sont inscrites comme suit :

  • Dépendant de l’infrastructure (par défaut) : les classes pouvant être activées sont ajoutées en tant qu’entrées <InProcessServer> dans le Package.appxmanifest
  • Autonome (--self-contained) : les classes activables sont incorporées dans des manifestes côte à côte (SxS) au sein de l’exécutable

Résolution d’espace réservé pendant l’empaquetage :

Si le manifeste contient $targetnametoken$ dans l’attribut Executable :

  1. Si --executable elle est fournie (chemin d’accès relatif au dossier d’entrée), l’espace réservé est remplacé par la valeur spécifiée.
  2. Dans le cas contraire, winapp pack analyse la racine du dossier d’entrée pour les .exe fichiers : si exactement un fichier est trouvé, il est utilisé automatiquement
  3. Si zéro ou plusieurs .exe fichiers sont trouvés, une erreur s’affiche pour vous demander de spécifier --executable

Exemples :

# Package directory with auto-detected manifest
winapp pack ./dist

# Package with custom output name and certificate
winapp pack ./dist --output MyApp.msix --cert ./cert.pfx

# Package with generated and installed certificate and self-contained WinAppSDK runtime
winapp pack ./dist --generate-cert --install-cert --self-contained

# Package with explicit executable (resolves $targetnametoken$ in manifest)
winapp pack ./dist --executable MyApp.exe

Offres groupées multi-architecture

Lorsque plusieurs dossiers d’entrée sont passés, winapp pack crée un .msixbundle conteneur par .msix architecture :

# Create unsigned bundle for Microsoft Store submission
winapp pack ./publish/x64 ./publish/arm64

# Create signed bundle for sideloading
winapp pack ./publish/x64 ./publish/arm64 --cert ./devcert.pfx

# Self-contained bundle
winapp pack ./publish/x64 ./publish/arm64 --self-contained --generate-cert

La commande détecte automatiquement l’architecture de chaque dossier à partir de l’en-tête PE du fichier exécutable principal, valide la cohérence entre les tranches (Identité, fonctionnalités, dépendances) et produit un <Name>_<Version>_<arch1>_<arch2>.msixbundle.

Résolution de manifeste pour les bundles :

Chaque tranche du bundle a besoin d’un manifeste. La commande résout les manifestes dans cet ordre :

  1. --manifest <path> — S’il est spécifié, ce manifeste unique est utilisé pour toutes les tranches. Il ProcessorArchitecture est automatiquement mis à jour par tranche pour correspondre à l’architecture détectée.

  2. Manifeste par dossier : si chaque dossier d’entrée contient un Package.appxmanifest (ou appxmanifest.xml), le manifeste de ce dossier est utilisé pour sa tranche.

  3. Secours du répertoire actif : si un dossier n’a pas de manifeste, la commande recherche Package.appxmanifest dans le répertoire de travail actuel et l’utilise (avec l’architecture auto-horodatée).

Dans tous les cas, le manifeste est automatiquement mis à jour : les espaces réservés sont résolus, les dépendances sont injectées et l’architecture détectée est définie sur force ProcessorArchitecture . Après la résolution, une validation inter-segments garantit que l’identité (nom, version, Publisher), les fonctionnalités et les dépendances sont cohérentes entre toutes les tranches. Elles peuvent uniquement ProcessorArchitecture différer. La version du package définie dans les tranches est attribuée à la version du bundle MSIX, sauf si elle est 0.0.0.0, auquel cas une version basée sur timestamp est générée automatiquement.

# Option 1: Single shared manifest (simplest for most projects)
# Place Package.appxmanifest in your project root and run from there
winapp pack ./publish/x64 ./publish/arm64

# Option 2: Explicit manifest path
winapp pack ./publish/x64 ./publish/arm64 --manifest ./src/Package.appxmanifest

# Option 3: Per-folder manifests (useful if slices have different app extensions)
# Each folder already contains its own Package.appxmanifest
winapp pack ./publish/x64 ./publish/arm64

create-debug-identity

Créez une identité d’application pour le débogage à l’aide d’un empaquetage partiellement alloué. L’exe reste dans son emplacement d’origine : Windows associe l’identité à celle-ci via Add-AppxPackage -ExternalLocation.

Quand utiliser ce fichier vs winapp run: utilisez create-debug-identity quand l’exe est distinct de votre code d’application (par exemple, applications Electron où electron.exe se trouve) node_modulesou lorsque vous testez spécifiquement le comportement du package éparse. Pour la plupart des frameworks où l’exe se trouve dans votre dossier de sortie de build, utilisez winapp run plutôt : il inscrit un package de disposition libre complet et lance l’application. Consultez le Guide de débogage pour obtenir une comparaison complète.

winapp create-debug-identity [entrypoint] [options]

Arguments :

  • entrypoint - Chemin d’accès à l’exécutable (.exe) ou script qui a besoin d’une identité

Options :

  • --manifest <path> - Chemin d’accès au fichier manifeste de l’application, soit Package.appxmanifestappxmanifest.xml (par défaut : détection Package.appxmanifest automatique ou appxmanifest.xml dans le répertoire actif)
  • --no-install - N’installez pas le package après la création
  • --keep-identity - Conservez l’identité du manifeste as-is, sans ajouter .debug le nom du package et l’ID d’application

Résultat :

  • Modifie le manifeste parallèle de l'exécutable
  • Enregistre le package clairsemé pour l'identité
  • Active le débogage des API nécessitant des identités

Exemples :

# Add identity to executable using local manifest
winapp create-debug-identity ./bin/MyApp.exe

# Add identity with custom manifest location
winapp create-debug-identity ./dist/app.exe --manifest ./custom-manifest.xml

# Create identity for hosted app script
winapp create-debug-identity app.py

embed-identity

Connectez une application de bureau à son package d’identité éparse en incorporant l’élément <msix> dans le manifeste côte à côte (fusion) de l’application. Il s’agit de l’étape 3 du flux de travail d’empaquetage partiellement alloué . Il indique Windows quel package d’identité appartient à l’exe en cours d’exécution.

winapp embed-identity <target> [options]

Arguments :

  • target - Fichier à mettre à jour. Détection automatique par extension :
    • .exe (Mode EXE) : incorpore l’élément <msix> directement dans le manifeste côte à côte de l’exe à l’aide mt.exede .
    • .xml / .manifest (mode XML) : insère ou remplace l’élément <msix> dans un fichier manifeste SxS externe (créé s’il n’existe pas). Regénérer votre application par la suite afin que le manifeste mis à jour soit incorporé dans le fichier binaire.

Options :

  • --manifest <path> - Chemin d’accès à l’identité éparse appxmanifest.xml à partir duquel lire l’identité (packageName, publisher, applicationId). En cas d’omission, la commande recherche un sparse/ dossier en regard de la cible, puis dans le répertoire actif, puis dans le répertoire actif et le répertoire actif.appxmanifest.xml

Exemples :

# EXE mode — embed identity straight into the built exe
winapp embed-identity ./bin/Release/net8.0-windows/MyApp.exe

# XML mode — update a checked-in side-by-side manifest, then rebuild
winapp embed-identity ./app.manifest --manifest ./appxmanifest.xml

Cette commande est idempotente : la réexécutation remplace tout élément existant <msix> plutôt que de le dupliquer.


manifeste

Générez et gérez des fichiers Package.appxmanifest.

générer un manifeste

Générez Package.appxmanifest à partir de modèles.

winapp manifest generate [directory] [options]

Arguments :

  • directory - Répertoire dans lequel générer le manifeste (par défaut : répertoire actif)

Options :

  • --package-name <name> - Nom du package (par défaut : nom du dossier)
  • --publisher-name <name>- Publisher nom unique (par défaut : CN=<current user>). Accepte un nom de domaine X.500 avec des composants séparés par des virgules (rdn multi-valeur et + barres obliques inverses ne sont pas pris en charge) ; les noms nus sont encapsulés automatiquement en tant que CN=<name>.
  • --version <version> - Version (par défaut : « 1.0.0.0 »)
  • --description <text> - Description (valeur par défaut : « Mon application »)
  • --entrypoint <path> - Exécutable ou script du point d’entrée
  • --template <type> - Type de modèle : packaged (par défaut) ou sparse
  • --logo-path <path> - Chemin d’accès au fichier image de logo
  • --if-exists <Error|Overwrite|Skip> - Comportement lorsque le fichier manifeste existe déjà au niveau du chemin d’accès cible (par défaut : Error)

Modèles:

Espaces réservés de manifeste

Les manifestes générés utilisent des jetons $placeholder$ (délimités par un signe dollar) qui sont résolus automatiquement au moment de l’empaquetage :

Espace réservé Résolu à Exemple
$targetnametoken$ Nom exécutable sans extension Executable="$targetnametoken$.exe" → Executable="MyApp.exe"
$targetentrypoint$ Windows.FullTrustApplication Toujours résolu automatiquement

Cela suit la même convention utilisée par Visual Studio modèles de projet, de sorte que les manifestes sont portables entre les outils.

Comment les espaces réservés sont gérés :

  • winapp pack — Pendant l’empaquetage, $targetnametoken$ est résolu à l’aide de l’option --executable ou en détectant automatiquement le single .exe dans le dossier d’entrée. Si plusieurs fichiers (ou zéro) .exe sont trouvés et --executable ne sont pas spécifiés, une erreur s’affiche.
  • winapp create-debug-identity — Lorsqu’un argument de point d’entrée est fourni, $targetnametoken$ il est résolu à partir de celui-ci. Sans point d’entrée, l’espace réservé exécutable doit déjà être résolu dans le manifeste.
  • winapp manifest generate --executable — Lorsqu’elles --executable sont fournies, les métadonnées du manifeste (version, description) et les icônes sont extraites de l’exécutable, mais le manifeste généré utilise $targetnametoken$.exetoujours ; cet espace réservé est résolu ultérieurement (par exemple winapp pack , ou winapp create-debug-identity).

PS : Conserver $targetnametoken$ dans votre manifeste archivé évite les noms exécutables codés en dur et fonctionne avec les builds winapp pack et Visual Studio.

Exemples :

# Generate standard manifest interactively
winapp manifest generate

# Generate with all options specified
winapp manifest generate ./src --package-name MyApp --publisher-name "CN=My Company" --if-exists overwrite

manifest add-alias

Ajoutez un alias d’exécution (uap5:AppExecutionAlias) à un Package.appxmanifest. Cela permet de lancer l’application empaquetée à partir de la ligne de commande en tapant le nom de l’alias.

winapp manifest add-alias [options]

Options :

  • --name <alias> - Nom d’alias (par exemple myapp.exe). Valeur par défaut : déduit de l’attribut Executable dans le manifeste.
  • --manifest <path> - Chemin d’accès à Package.appxmanifest (par défaut : rechercher dans le répertoire actif)
  • --app-id <id> - ID d’application pour ajouter l’alias à (par défaut : premier élément Application)

Résultat :

  • Lit le manifeste et déduit l’alias de l’attribut Executable (préservation des espaces réservés comme $targetnametoken$.exe)
  • Ajoute la déclaration d’espace de noms s’il n’est uap5 pas déjà présent
  • Ajoute un <Extensions> bloc avec <uap5:AppExecutionAlias> l’élément Application cible
  • Si l’alias existe déjà, le signale et se ferme correctement

Exemples :

# Add alias inferred from Executable attribute (e.g. $targetnametoken$.exe)
winapp manifest add-alias

# Add alias with explicit name
winapp manifest add-alias --name myapp.exe

# Add alias to specific manifest
winapp manifest add-alias --manifest ./dist/Package.appxmanifest

manifeste mettre à jour les assets

Générez toutes les ressources d’image MSIX requises à partir d’une seule image source.

winapp manifest update-assets <image-path> [options]

Arguments :

  • image-path - Chemin d’accès au fichier image source (PNG, JPG, SVG, ICO, GIF, BMP, etc.)

Options :

  • --manifest <path> - Chemin d’accès au fichier Package.appxmanifest (par défaut : rechercher dans le répertoire actif)
  • --light-image <path> - Chemin d’une image source distincte pour les variantes de thème clair

Description:

Prend une image source unique et génère un ensemble complet de ressources d’image MSIX en fonction des références d’éléments multimédias du manifeste :

Pour chaque ressource référencée dans le manifeste :

  • 5 variantes d’échelle — base (pas de suffixe), .scale-125, .scale-150, .scale-200, .scale-400

Pour l’icône d’application (Square44x44Logo / AppList, 44×44 base) :

  • 14 cibles platesize de variantes — .targetsize-{16,20,24,30,32,36,40,48,60,64,72,80,96,256}
  • 14 cibles nonplatéesizent des variantes — .targetsize-{size}_altform-unplated

De plus:

  • app.ico — Fichier ICO à résolution multiple (16, 24, 32, 48, 256) pour l’intégration de l’interpréteur de commandes. Si un fichier existant .ico se trouve dans le répertoire des ressources (par exemple, AppIcon.ico à partir d’un modèle de projet), il est remplacé sur place plutôt que de créer un doublon

Avec --light-image :

  • Thème clair cible les variantes — .targetsize-{size}_altform-lightunplated (icône d’application)
  • Variantes d’échelle de thème clair — .scale-{factor}_altform-colorful_theme-light (vignettes, logo de magasin)

Prise en charge SVG : Les fichiers SVG sont entièrement pris en charge en tant qu’images sources. Ils sont rendus en tant que vecteurs directement à chaque taille cible, produisant des résultats parfaits en pixels à toutes les résolutions. Le fichier doit déclarer sa propre taille, par le biais d’un viewBox ou d’un attribut absolu width et height d’un pourcentage viewBox sans aucune taille particulière. Source qui déclare que ni l’un ni l’autre n’est rejeté au SVG image has no usable dimensions lieu de produire des ressources vides.

La commande met à l’échelle les images proportionnellement tout en conservant les proportions, en les centreant avec des arrière-plans transparents si nécessaire. Les ressources sont enregistrées dans le répertoire Assets par rapport à l’emplacement du manifeste.

Exemples :

# Generate assets with auto-detected manifest
winapp manifest update-assets mylogo.png

# Use an SVG source for best quality at all sizes
winapp manifest update-assets mylogo.svg

# Specify manifest location explicitly
winapp manifest update-assets mylogo.png --manifest ./dist/Package.appxmanifest

# Generate light theme variants from a separate image
winapp manifest update-assets mylogo.png --light-image mylogo-light.png

# Use the same image for both (generates all MRT light theme qualifiers)
winapp manifest update-assets mylogo.png --light-image mylogo.png

# With verbose output
winapp manifest update-assets mylogo.png --verbose

Courir

Créez un package de disposition libre à partir d’un dossier de sortie de build, inscrivez-le auprès de Windows à l’aide de l’API Windows.Management.Deployment.PackageManager et lancez l’application , en simulant une installation MSIX complète pour le débogage. Retourne l’ID de processus pour la pièce jointe du débogueur.

winapp run fonctionne dans l’un des trois modes, choisi automatiquement à partir de l’entrée :

  • Mode dossier : l’entrée est un dossier de sortie de build (contient un Package.appxmanifest/AppxManifest.xml).
  • Project mode : l’entrée est un .csproj, un C++ .vcxproj, une .sln/.slnx solution ou un répertoire contenant un. winapp rungénère le projet et le lance, prenant en charge les applications empaquetées et non empaquetées. Consultez les projets Project mode et C++ ci-dessous.
  • Mode fichier unique : l’entrée est une .csapplication basée sur des fichiers .NET. winapp run génère un manifeste à partir de ses #:property directives et le lance avec une identité de package.

Tip

La sélection du mode est silencieuse par défaut. Si un répertoire a été traité comme un dossier de sortie de build lorsque vous vous attendiez à ce qu’il soit généré en tant que projet, réexécutez avec --verbose — le mode dossier indique pourquoi il a été choisi (No .csproj/.vcxproj/.sln/.slnx with a runnable app found in '<path>' — running it as a build-output folder.). Un répertoire est généré uniquement en tant que projet lorsqu’une .csproj.sln///.vcxproj.slnx application runnable se trouve à son niveau supérieur ; elle n’est pas recherchée de manière récursive.

Cette commande est la commande préférée pour le débogage avec l’identité de package pour la plupart des frameworks (.NET, C++, Rust, Flutter, Tauri). Contrairement create-debug-identity à ce qui enregistre un package partiellement alloué pour un seul exe, winapp run inscrit l’intégralité du dossier en tant que package de disposition libre, tout comme une véritable installation MSIX. Consultez le Guide de débogage pour les flux de travail de débogage courants.

winapp run [<input>] [options]

Arguments :

  • input- L’application à exécuter : un dossier de génération (mode dossier), une application basée sur un .cs fichier .NET (mode fichier unique), un .csproj projet ou C++.vcxproj, une .sln/.slnx solution ou un répertoire contenant l’un de ceux de son niveau supérieur (mode projet ; le répertoire n’est pas recherché de manière récursive). Permet . de générer/exécuter le projet dans le répertoire actif. Facultatif : valeur par défaut du répertoire actif lorsqu’il est omis (correspond dotnet run).

Options :

  • --manifest <path> - Chemin d’accès à Package.appxmanifest (par défaut : détection automatique à partir du dossier d’entrée ou du répertoire actif)
  • --output-appx-directory <path> - Répertoire de sortie de la disposition libre (par défaut : AppX à l’intérieur du dossier d’entrée). La disposition par défaut supprime les fichiers qui ne sont plus dans la build ; un répertoire personnalisé conserve des fichiers supplémentaires. Utilisez un répertoire personnalisé nouveau lorsque vous avez besoin d’une disposition propre.
  • --args <string> - Arguments de ligne de commande à passer à l’application. Vous pouvez également utiliser -- suivi d’arguments pour éviter l’échappement (par exemple). winapp run . -- --flag value
  • --no-launch - Créez uniquement l’identité de débogage et inscrivez le package sans lancer l’application.
  • --with-alias - Lancez l’application à l’aide de son alias d’exécution au lieu de l’activation AUMID. L’application s’exécute dans le terminal actuel avec stdin/stdout/stdout/stderr hérité. Rarement nécessaire : une application avec OutputType=Exe déjà lancé cette façon par défaut. winapp ajoute le manifeste requis uap5:ExecutionAlias aux étapes de la disposition AppX. Par conséquent, aucune modification de votre manifeste archivé n’est nécessaire ; un alias que l’application déclare elle-même est utilisé as-is. Impossible de combiner avec --no-launch, , --detach--without-aliasou --json.
  • --without-alias - Forcer l’activation AUMID pour une application qui s’exécuterait autrement par le biais d’un alias d’exécution. Une application console s’exécute ensuite sans console et n’imprime rien dans ce terminal. Impossible de combiner avec --with-alias.
  • --debug-output - Capturez les OutputDebugString messages et les exceptions de première chance de l’application lancée. Le bruit de l’infrastructure (WinUI, COM, DirectX) est filtré à partir de la sortie de la console ; le fichier journal complet capture tout. Si l’application se bloque, capture automatiquement un minidump et l’analyse pour afficher le type d’exception, le message et la trace de pile avec des numéros de ligne de fichier source (résolus à partir de fichiers PDB dans le dossier de sortie de build). Les incidents managés (.NET) sont analysés instantanément sans outils externes. Les blocages natifs (C++/WinRT) affichent les noms et les décalages des modules. Lorsque l’application bloquée est une application WinUI 3 (Microsoft.UI.Xaml.dll est chargée), un passe de triage d’exception supplémentaire s’exécute automatiquement pour exposer automatiquement hrESULT d’origine, sa chaîne ErrorContext et la pile de répartition XAML native complète ; les composants de débogueur requis sont téléchargés lors de la première utilisation (voir Débogage, substituable via la WINAPP_DBGTOOLS_DIR variable d’environnement). Un seul débogueur peut s’attacher à un processus à la fois, de sorte que d’autres débogueurs (Visual Studio, VS Code) ne peuvent pas être utilisés simultanément. Utilisez --no-launch plutôt si vous devez attacher un autre débogueur. Impossible de combiner avec --no-launch. Impossible de combiner avec --json. Si vous exécutez sans celui-ci et que l’application quitte avec un code différent de zéro, winapp imprime un indicateur pour réexécuter avec --debug-output.
  • --symbols - Téléchargez des symboles PDB à partir de Microsoft Serveur de symboles pour une analyse de plantage native plus riche avec des noms de fonction résolus. Utilisé uniquement avec --debug-output. S’il est omis et qu’un incident natif se produit, la sortie suggère d’ajouter cet indicateur. Cet indicateur améliore également la pile de triage des exceptions de WinUI pour les applications WinUI 3. La première exécution télécharge les symboles et les met en cache localement ; les exécutions suivantes utilisent le cache.
  • --unregister-on-exit - Annulez l’inscription du package de développement après la fermeture de l’application. Supprime uniquement les packages inscrits en mode de développement. Impossible de combiner avec --no-launch.
  • --detach - Lancez l’application et revenez immédiatement sans attendre qu’elle se termine. Utile pour l’automatisation/ci où vous devez interagir avec l’application après le lancement. Les exécutions locales impriment le PID ; les exécutions cibles impriment la cible d’interface utilisateur délimitée. JSON inclut l’étendue PID et cible. Impossible de combiner avec --no-launch, , --debug-output--with-aliasou --unregister-on-exit.
  • --clean - Supprimez les données d’application du package existant (LocalState, paramètres, etc.) avant le nouveau déploiement. Par défaut, les données d’application sont conservées entre les redéploiements.
  • --json - Mettre en forme la sortie au format JSON pour la consommation par programmation (par exemple, CI/automation). Utile pour --detach capturer le PID. Impossible de combiner avec --with-alias ou --debug-output.
  • --on <target> - Générez sur l’hôte, puis inscrivez et exécutez-le dans la cible. Prend actuellement en charge sandbox, sans secours à l’exécution locale. Utilisez --detach avant les commandes d’interface utilisateur de suivi. Le bac à sable --debug-output nécessite une application empaquetée. Consultez Windows exécution du bac à sable pour la configuration, la prise en charge du runtime et la durée de vie des applications détachées.

Persistance des données d’application :

Par défaut, winapp run conserve les données de votre application (LocalState, RoamingState, Settingsetc.) lors du redéploiement. Si votre application écrit des données dans ApplicationData.Current.LocalFolder ou Environment.GetFolderPath(SpecialFolder.LocalApplicationData) dans le contexte du package, ces données survivent entre winapp run les appels.

Utilisez --clean quand vous avez besoin d’un nouveau démarrage (par exemple, pour réinitialiser l’état endommagé ou tester le comportement de première exécution).

Résultat :

  • Recherche ou génère package.appxmanifest
  • Crée et inscrit une identité de débogage à l’aide d’un package de disposition libre
  • Calcule l’ID de modèle utilisateur d’application (AUMID)
  • Lance l’application à l’aide de l’identité inscrite (sauf --no-launch indication contraire)
  • Imprime l’ID de processus (PID) pour la pièce jointe du débogueur

Exemples :

# Register debug identity and launch app from build output
winapp run ./bin/Debug

# Launch with custom manifest and arguments
winapp run ./dist --manifest ./out/Package.appxmanifest --args "--my-flag value"

# Pass arguments after -- to avoid escaping (equivalent to --args)
winapp run ./bin/Debug -- --my-flag value

# Specify output directory for loose layout package
winapp run ./bin/Release --output-appx-directory ./AppXDebug

# Register identity without launching
winapp run ./bin/Debug --no-launch

# Launch via execution alias (console apps run in current terminal)
winapp run ./bin/Debug --with-alias

# Launch and capture OutputDebugString messages and crash diagnostics
winapp run ./bin/Debug --debug-output

# Download native symbols for richer crash analysis (C++/WinRT crashes)
winapp run ./bin/Debug --debug-output --symbols

# Combine with execution alias to debug console apps inline
winapp run ./bin/Debug --with-alias --debug-output

# Run and automatically clean up registration on exit
winapp run ./bin/Debug --with-alias --unregister-on-exit

# Launch and detach immediately (useful for CI/automation)
winapp run ./bin/Debug --detach

# Detach with JSON output (returns PID for scripting)
winapp run ./bin/Debug --detach --json

# Wipe application data (LocalState, settings) and start fresh
winapp run ./bin/Debug --clean

mode Project (projets sdk .NET)

Lorsque l’entrée est un .csproj, une/.slnx.slnsolution ou un répertoire contenant un (y compris.), winapp rungénère le projet avecdotnet build, puis le lance. Il prend en charge les applications WinUI empaquetées et non empaquetées et installe l’architecture correspondante application Windows Runtime dont l’application a besoin avant le lancement.

Entrée de solution : pointez winapp run sur un .sln/.slnx (ou un répertoire contenant un répertoire , une solution est préférée aux fichiers libres.csproj) et résout le projet d’application exécutable, puis le génère avec $(SolutionDir) et les propriétés frères Solution* définies, de sorte que les projets qui dépendent de ces derniers soient générés comme ils le font dans Visual Studio. Règles de résolution :

  • Les projets de test sont ignorés lors de la sélection automatique. Par conséquent, une solution contenant une application ainsi que ses tests sont résolus sur l’application sans qu’elle soit --project nécessaire. (Un projet de test WinUI est lui-même une application empaquetée, de sorte que le type de sortie seul ne peut pas le distinguer.)
  • Si le seul projet exécutable est un projet de test, il s’exécute.
  • Si plusieurs projets d’application exécutables existent, winapp run ne suppose pas qu’un projet de démarrage n’est pas deviné : il est erroné de répertorier les candidats. Permet --project <name> de choisir, qui est toujours honoré, y compris pour sélectionner un projet de test.

Empaqueté ou non empaqueté est détecté automatiquement à partir de la propriété MSBuild effective WindowsPackageType du projet (jamais à partir de la présence du manifeste) :

  • Empaquetée (WindowsPackageType=MSIXpar défaut, winUI empaquetée par défaut), enregistre la sortie de build en tant que package de disposition libre et démarre via AUMID (le même pipeline que le mode dossier).
  • Unpackaged (WindowsPackageType=None) : génère des builds, garantit que le application Windows runtime dépendant de l’infrastructure est installé, puis lance le runtime généré .exe directement. Forcez cette opération pour un projet empaqueté avec -p WindowsPackageType=None.

Project mode nécessite le sdk .NET 8.0.100 ou version ultérieure (pour MSBuild--getProperty).

AOT natif : ajoutez ce groupe de propriétés à l'intérieur de l'élément du <Project> fichier project, puis ajoutez --aot:

<PropertyGroup>
  <PublishAot>true</PublishAot>
</PropertyGroup>
winapp run . --aot
winapp run . --aot -c Release

--aotprend en charge les projets x64 et ARM64 et nécessite le sdk .NET 8.0.300 ou ultérieur. Elle s’exécute dotnet publish avec la configuration AOT du projet, puis lance cette sortie ; elle est utilisée -p PublishAot=true pour un remplacement unique. Elle n’effectue pas de certification d’exécution distincte et ne peut pas être combinée avec --no-build ou --manifest.

Pour les applications qui utilisent l’identité de package sans disposition MSIX générée, incluez Package.appxmanifest ou appxmanifest.xml dans la sortie de publication du projet. Winapp met en scène les fichiers publiés avec ce manifeste. Si les deux noms sont présents, winapp s’arrête au lieu de choisir un nom ; supprimez le manifeste obsolète et configurez le projet pour publier uniquement le manifeste prévu.

options Project-mode (ignorées en mode dossier, sauf indication contraire) :

  • -c, --configuration <name> - Configuration de build. Valeur par défaut : Debug. (Également honoré en mode fichier unique.)
  • --arch <x64|arm64|x86> - Architecture cible. Valeur par défaut : architecture de processus actuelle. Détermine le RID de build et l’architecture d’exécution application Windows, puis sélectionne un profil de publication dépendant de la plateforme correspondant si nécessaire par la build effective. (Également honoré en mode fichier unique.)
  • -r, --runtime <rid>- Identificateur d’exécution .NET cible (par exemplewin-x64). Project mode utilise uniquement l'architecture du RID, génère toujours le canonique win-<arch>et rejette les RID non Windows (par exemplelinux-x64). Son architecture remplace --arch et peut sélectionner le profil de publication requis. (Également honoré en mode fichier unique, où il remplace un #:property RuntimeIdentifier déclaré par le fichier.)
  • -f, --framework <tfm> - Moniker de framework cible pour les projets multi-ciblés (par exemple net10.0-windows10.0.26100.0). (Rejeté en mode fichier unique : utilisez #:property TargetFramework=....)
  • --project <name-or-path> - Lorsque l’entrée est une solution (.sln/.slnx) ou un répertoire avec plusieurs projets d’application exécutables, sélectionne le projet à lancer (par nom de projet ou chemin d’accès). (Rejeté en mode fichier unique : une application basée sur un .cs fichier est elle-même le projet.)
  • --no-build - Ignorez la génération et exécutez la sortie de build existante (évalue toujours les propriétés de sortie). (Également honoré en mode fichier unique.)
  • --no-restore - Ignorez la restauration avant la création ou la publication AOT native. (Également honoré en mode fichier unique.)
  • --aot- Exécutez le projet configuré .NET publication AOT native. Nécessite une efficacité PublishAot=true. Rejeté dans les modes dossier et fichier unique.
  • -p, --property <Name=Value> - Propriété MSBuild, transférée à la fois à la build et à l’évaluation des propriétés. Répétez cette opération -p pour plusieurs propriétés ; utilisez %3B ou %2C pour un point-virgule littéral ou une virgule dans une valeur. (Également honoré en mode fichier unique, où il s’agit de la seule façon de définir TargetFramework.)

Sortie de build & verbosity : une exécution de projet ordinaire utilise dotnet build, puis évalue la sortie générée. Restaurez et générez le flux de sortie en direct, avec les informations d’identification des URL de flux authentifiées régérées. Avec --aot, winapp utilise dotnet publish; --verbose affiche la commande de publication et les chemins résolus. Utilisez les options de détail ci-dessous pour contrôler ce qui est affiché :

Flag dotnet verbosity Ajoute
(par défaut) minimal —
--verbose minimal Traces de décision de génération de winapp
--quiet quiet —

Les flux de sortie de publication AOT natifs à mesure qu’il arrive. Sous --json, les appels de restauration/génération et la sortie enfant vont à stderr afin que stdout reste pur JSON. Sous --quiet, les appels sont supprimés et la sortie de restauration/génération silencieuse de dotnet est acheminée vers stderr afin que stdout reste propre. La sortie de publication AOT native est également envoyée à stderr sous l’une ou l’autre option.

Applicabilité des options d’option : les options d’identité/de disposition libre (--manifest, --output-appx-directory, --no-launch, --with-alias--unregister-on-exit, --clean, , --executable) s’appliquent uniquement aux applications empaquetées. Ils sont rejetés avec une erreur claire pour les applications non empaquetées (qui n’ont pas de package MSIX). Les options de lancement/débogage (--args/--, , --detach, --symbols--debug-output, --json) fonctionnent dans les deux.

exemples en mode Project :

# Build and run the project in the current directory (input defaults to ".")
winapp run

# Run a specific project
winapp run ./src/MyApp/MyApp.csproj

# Build and run from a solution (resolves the runnable app project, defines $(SolutionDir))
winapp run ./MyApp.sln

# Pick a startup project when the solution has more than one runnable app
winapp run ./MyApp.sln --project MyApp

# Release build for arm64
winapp run . -c Release --arch arm64

# Publish and run the Release configuration with Native AOT
winapp run . --aot -c Release

# Force an unpackaged run of a packaged project
winapp run . -p WindowsPackageType=None

# Run the existing build output without rebuilding, and capture crash diagnostics
winapp run . --no-build --debug-output

# Show winapp's build decision traces (dotnet build stays at minimal verbosity)
winapp run . --verbose

# Launch and detach (prints PID), forwarding args to the app
winapp run . --detach -- --my-flag value

Projets C++ (.vcxproj)

Pointez winapp run sur un .vcxproj dossier ou une solution dont seule l'application exécutable est une et qu'elle génère le projet avec MSBuild de Visual Studio, puis la lance de la même façon qu'un projet .NET :

winapp run .\MyApp.vcxproj
winapp run . -c Release --arch arm64
winapp run . --no-build --detach --json
  • Une application WinUI 3 C++/WinRT à partir du modèle d’application vide WinUI (empaquetée) Visual Studio s’exécute empaquetée. D’autres projets d’application, tels qu’une application console ou une application WinUI créée avec -p WindowsPackageType=None, s’exécutent non empaquetés à partir de leur application générée .exe.
  • Builds Debug pour l’architecture actuelle par défaut. --arch x64|arm64|x86 ou -p Platform=x64|ARM64|Win32 sélectionne l’architecture (en passant les deux avec des architectures différentes est une erreur) ; un nom personnalisé -p Platform est transmis.
  • Restaure d’abord les packages.config packages NuGet (ignorer avec --no-restore) et installe la version application Windows Runtime qu’ils épinglent. Les applications empaquetées obtiennent également les packages d’infrastructure les références de build, telles que le runtime VC++ de débogage, installé lorsqu’il est manquant.
  • --frameworket --aot s’applique uniquement aux projets .NET.
  • La sortie de build affiche uniquement les avertissements et erreurs de MSBuild, avec un spinner pendant sa génération ; --verbose affiche la sortie complète de MSBuild et la commande exacte.
  • Dans un dossier ou une solution qui a également une application C# exécutable, l’application C# est sélectionnée ; permet --project <name> d’exécuter l’application C++. Les bibliothèques C# et les projets de test en regard d’une application C++ ne sont pas disponibles.
  • Une application C# qui fait référence à un projet C++ (par exemple une DLL native) ne peut pas être générée avec dotnet. Générez-le avec Visual Studio ouMSBuild.exe, puis exécutez, ou empaquetez winapp run <app>.csproj --no-buildson dossier de sortie avec winapp package <folder>.

Conditions préalables : Visual Studio ou Build Tools pour Visual Studio 2022 version 17.8 ou ultérieure, avec les outils de génération MSVC C++ pour l’architecture cible (développement Desktop avec charge de travail C++) et le sdk Windows cibles du projet. Les applications WinUI 3 ont également besoin d’outils de développement d’applications WinUI C++ ; avec plusieurs installations, winapp utilise le plus récent qui peut générer le projet. Le Kit de développement logiciel (SDK) .NET n’est pas obligatoire. Lorsque les outils de génération, l’ensemble d’outils de plateforme (MSB8020) ou Windows SDK (MSB8036) sont manquants, winapp run indique ce qu’il faut installer, y compris une winget commande.

Consultez l’exemple cpp-winui-app.

Mode à fichier unique (applications basées sur des fichiers .NET)

.NET 10 vous permet d’exécuter un fichier unique .cs sans fichier projet, en le configurant avec #: des directives en haut. Pointez winapp run sur ce fichier et il génère l’application, génère un appxmanifest pour celui-ci et le lance avec l’identité du package . Windows.ApplicationModel.Package.Current Ainsi, l’application obtient une entrée AUMID réelle et une entrée de menu Démarrer, et les API qui nécessitent simplement l’identité (notifications d’application, ApplicationDatal’IA sur l’appareil) fonctionnent.

Les intégrations shell telles que les gestionnaires de protocole, les associations de fichiers, les cibles de partage et les tâches de démarrage nécessitent une entrée déclarée <Extensions> , que le manifeste généré ne contient pas. Pour en ajouter un, créez votre propre manifeste . Consultez Apporter votre propre manifeste ci-dessous.

winapp run counter.cs

Ou exécutez-la avec une valeur simple dotnet run : voir Exécution avec dotnet run ci-dessous.

Vous ne créez pas de manifeste. Décrivez le package avec #:property des directives à la place :

#:package Microsoft.UI.Reactor@0.1.0-preview.13
#:property OutputType=WinExe
#:property TargetFramework=net10.0-windows10.0.22621.0
#:property UseWinUI=true
#:property RuntimeIdentifier=win-x64

#:property WinAppPackageName=com.contoso.counter
#:property WinAppDisplayName=Contoso Counter
#:property WinAppDescription=Counts things, one click at a time
#:property Version=1.2.3

using static Microsoft.UI.Reactor.Factories;
ReactorApp.Run<MyApp>("Hello");

Propriétés du manifeste. Tous sont facultatifs ; chacun revient à une valeur par défaut sensible :

Propriété Ensembles Default
WinAppPackageName Identity/@Name (l’identité du package) le nom du fichier, nettoyé à [-.A-Za-z0-9], plus un hachage court du chemin d’accès du fichier (counter.cs → counter-a1b2c3d4)
WinAppDisplayName Nom affiché dans Démarrer et Paramètres nom de fichier sans son extension
WinAppPublisher Identity/@Publisher CN=<your Windows user name>. Un nom nu est encapsulé en tant que CN=<name>.
WinAppVersion Identity/@Version $(Version), normalisé (voir ci-dessous)
WinAppDescription Description affichée lors de l’installation et des paramètres nom complet
WinAppCapabilities Fonctionnalités à déclarer, séparées par ; ou , aucune

Version. Une version de package doit être exactement quatre nombres, chacun 0 à 65535. WinAppVersion (ou, si vous ne le définissez pas, la propriété standard Version ) est normalisée pour s’adapter : -preview/-rc Le suffixe est supprimé et les composants manquants sont remplis de zéros, de sorte qu’ils deviennent #:property Version=1.2.3-preview.41.2.3.0 et définissent ensemble la version de votre assembly et de votre version de package. Une valeur qui ne peut pas être adaptée ( un composant supérieur à 65535, ou plus de quatre composants) est rejetée avec une erreur plutôt qu’une modification silencieuse.

Capacités

Votre application exécute une confiance totale avec l’identité, ce qui satisfait aux API qui nécessitent uniquement une application empaquetée. Toutefois, certaines API sont contrôlées sur une fonctionnalité déclarée, quel que soit le cas, les API d’IA Windows sont le cas courant. (Les intégrations shell, telles que les gestionnaires de protocole et les associations de fichiers, sont un troisième cas : celles qui ont besoin d’entrées créées <Extensions> , et non d’une fonctionnalité, utilisent donc votre propre manifeste pour eux.)

#:property WinAppCapabilities=systemAIModels

Il s’agit de toutes les API de modèle Phi Silicon et d’autres API de modèle sur appareil nécessaires à partir du manifeste. Déclarez plusieurs en les séparant :

#:property WinAppCapabilities=systemAIModels;internetClient;microphone

winapp écrit chacun d’eux dans l’élément et l’espace de noms XML dont il a réellement besoin, déclare cet espace de noms et déclenche MaxVersionTested quand la fonctionnalité a besoin d’un espace de noms plus récent. Cela importe plus que cela : les fonctionnalités sont réparties sur plusieurs éléments différents, et la même liste ci-dessus devient trois formes différentes :

<systemai:Capability Name="systemAIModels" />
<Capability Name="internetClient" />
<DeviceCapability Name="microphone" />

Les noms winapp savent qu’ils sont écrits pour vous. Pour tout autre chose — le jeu restreint augmente au fil du temps — qualifiez-le vous-même avec le préfixe d’espace de noms :

Préfixe Émettre
rescap: <rescap:Capability> — fonctionnalités restreintes
uap:, , uap6:uap7:, ,uap11: <uap*:Capability>
systemai: <systemai:Capability>
device: <DeviceCapability>
app: <Capability> dans l’espace de noms par défaut
#:property WinAppCapabilities=rescap:broadFileSystemAccess

Un nom nu non reconnu est rejeté avec une erreur nommant ces préfixes, au lieu d’être deviné : une fonctionnalité émise dans l’espace de noms incorrect produit un manifeste Windows refuse d’inscrire ou d’accepter sans assistance.

Apportez votre propre manifeste

Si vous avez besoin de quelque chose que les propriétés ne couvrent pas ( un gestionnaire de protocole, une association de fichiers, un alias d’exécution), créez un manifeste et winapp run utiliserez-le au lieu de générer un manifeste. Il est récupéré, dans l’ordre :

  1. --manifest <path> sur la ligne de commande.
  2. #:property WinAppManifestPath=<path> dans le .cs fichier.
  3. Manifeste situé à côté du .cs fichier, nommé <filename>.appxmanifest (par exemple counter.appxmanifest à côté counter.cs).

Seul ce nom par fichier est récupéré automatiquement. Un Package.appxmanifest ou appxmanifest.xml dans le même dossier est délibérément ignoré : plusieurs .cs fichiers peuvent partager un dossier et l’adoption d’un nom partagé exécuterait silencieusement une application sous l’identité d’un autre. Pour utiliser un manifeste pour plusieurs fichiers, nommez-le explicitement avec --manifest ou WinAppManifestPath.

Sinon, une Package.appxmanifest valeur est générée dans la sortie de build, ainsi que les ressources d’image par défaut et actualisées à chaque exécution.

Options. Chaque option en mode dossier fonctionne : --no-launch, , --with-alias, --detach--debug-output--clean--without-alias--symbols--json/--unregister-on-exit----args, --executable--manifest--output-appx-directoryplus -c/--configuration, --no-build, et . --no-restore-p/--property

Tip

Une application console s’imprime sur votre terminal par défaut. Une application empaquetée lancée via AUMID n’a pas de console, donc une application console uniquement s’exécuterait correctement et n’imprime rien. winapp évite cela : une application avec est OutputType=Exe lancée via un alias d’exécution à la place, qui hérite de stdin/stdout/stderr de ce terminal. Vous obtenez toujours l’identité du package et vous n’avez pas besoin de lui demander :

winapp run counter.cs

--without-alias Passez à forcer l’activation AUMID à la place : l’application s’exécute ensuite sans console et n’imprime rien ici. Une application fenêtré (WinExe) affiche une fenêtre, de sorte qu’elle conserve l’activation AUMID ; passe --with-alias si vous en voulez une dans ce terminal de toute façon. Pour corriger le choix dans le fichier plutôt que sur chaque ligne de commande, définissez la même propriété qu’une .csproj utilisation :

#:property WinAppRunUseExecutionAlias=false

L’alias winapp déclare est nommé après le nom de la famille de packages, avec un winapp- préfixe , ainsi com.contoso.counter publié par CN=You obtient winapp-com.contoso.counter_gspb8g6x97k2t.exe. Cette partie de fin est le hachage de l’éditeur Windows dérive, donc deux applications partageant un nom sous différents éditeurs obtiennent toujours des alias différents. Le préfixe conserve le nom clair des commandes réelles : une application obtient python.cs un winapp-… alias, jamais python.exe. Si vous créez votre propre manifeste, l’alias que vous déclarez est utilisé as-is et winapp n’ajoute rien.

Cela s’applique uniquement à l’alias. L’inscription elle-même est clé sur le nom du package. Par conséquent, l’exécution d’une deuxième application qui déclare la même WinAppPackageName sous un autre éditeur remplace la première inscription plutôt que de s’asseoir à côté de celle-ci. Donnez à chaque application son propre nom si vous souhaitez que les deux soient inscrites à la fois.

winapp run imprime l’alias qu’il a inscrit. Vous n’avez donc pas besoin de calculer le hachage pour le trouver.

L’alias est une commande sur votre CHEMIN d’accès qui dure tant que le package reste inscrit. Si un autre package possède déjà le nom, winapp le dit. Lorsqu’il déduit l’alias pour vous qu’il démarre via AUMID à la place, plutôt que de démarrer l’application incorrecte ; lorsque vous en avez demandé un explicitement — avec --with-alias ou #:property WinAppRunUseExecutionAlias=true — il échoue au lieu de faire tranquillement quelque chose d’autre.

Deux options en mode projet ne s’appliquent pas , car une application basée sur un fichier se configure elle-même. Ils sont rejetés avec un message nommant la directive à utiliser à la place :

Choix Utiliser à la place
-f/--framework #:property TargetFramework=net10.0-windows10.0.22621.0
--project rien — le .cs fichier est le projet

--arch et -r/--runtime fonctionnent comme ils le font en mode projet. Lorsque vous ne passez pas non plus, winapp génère des builds pour l'architecture de votre machine, c'est-à-dire ce dont a besoin une application autonome SDK d'application Windows, car sans elle, le SDK génère AnyCPU et échoue avec WindowsAppSDKSelfContained requires a supported Windows architecture. Un #:property RuntimeIdentifier=win-arm64 fichier est respecté ; un remplacement explicite --arch/--runtime le remplace.

Empaquetée et non empaquetée, détectée à partir de l’effectif WindowsPackageType exactement comme en mode projet : la disposition par défaut inscrit une disposition libre et la lance avec l’identité, tandis que #:property WindowsPackageType=None génère l’application, installe la correspondance application Windows Runtime et lance directement l’application.exe. (Une application empaquetée est lancée par le biais de son alias d’exécution ou par le biais de l’activation AUMID : consultez la note de console ci-dessus ; ce choix est distinct du fait qu’il soit empaqueté.) Les options d’identité (--no-launch, , --with-alias, --without-alias--clean, --unregister-on-exit, --manifest) --output-appx-directorys’appliquent uniquement aux applications empaquetées.

Exécution avec dotnet run

Vous n’avez pas à taper winapp du tout. Référencez le Microsoft.Windows.SDK.BuildTools.WinApp package à partir du fichier et vous dotnet run donnez simplement le même lancement empaqueté :

#:package Microsoft.Windows.SDK.BuildTools.WinApp@*
#:property OutputType=Exe
#:property TargetFramework=net10.0-windows10.0.19041.0

System.Console.WriteLine(Windows.ApplicationModel.Package.Current.Id.FamilyName);
dotnet run counter.cs

Les cibles MSBuild du package redirigent l’exécution vers winapp, quels packages, s’inscrit et lance l’application qui dotnet run vient d’être créée, mais elle n’est pas reconstruite. La gestion des manifestes n’est pas modifiée : winapp le résout exactement comme il le fait pour winapp run, ainsi #:property WinAppManifestPath=… qu’à <filename>.appxmanifest côté des .cs deux sont honorés (voir Bring your own manifest), un répertoire à l’échelle Package.appxmanifest de l’annuaire est toujours ignoré, et sinon il est généré à partir de vos #:property directives et actualisé chaque exécution.

Deux conditions doivent être en attente pour que la redirection se produise :

Directive Pourquoi
#:package Microsoft.Windows.SDK.BuildTools.WinApp@* les cibles qui effectuent l’expédition de redirection dans ce package
#:property TargetFramework=net10.0-windows… un fichier brut net10.0 est laissé seul, il s’exécute donc non empaqueté

L’ajout #:property WindowsPackageType=None laisse également le fichier seul : dotnet run exécute ensuite directement .exe , sans identité. Utilisez winapp run le chemin d’accès non empaqueté si vous souhaitez d’abord installer la application Windows Runtime correspondante.

Définissez #:property EnableWinAppRunSupport=false la désactivation complète de la redirection et les WinAppRun* propriétés décrites sous Configuration pour mettre en forme le lancement , par exemple :

#:property WinAppRunUnregisterOnExit=true

Si dotnet run vous exécutez l’application non empaquetée lorsque vous attendez une identité, demandez à MSBuild pourquoi. Utilisez dotnet build, pas dotnet msbuild seulement dotnet build — synthétise le projet virtuel qu’une application basée sur un fichier est compilé par le biais de :

dotnet build counter.cs -t:WinAppRunSupportInfo

Le mode fichier unique nécessite le sdk .NET 10.0.300 ou version ultérieure.

L’inscription est en cours d’exécution. winapp run counter.cs quitte le package inscrit après la fermeture de l’application, exactement comme le mode dossier et projet. Par conséquent LocalState , la réexécutation du même fichier réutilise la même identité plutôt que d’empiler les inscriptions. winapp dit donc la première fois qu’elle inscrit une application et winapp unregister prend la .cs même chose :

# Remove the registration (resolves the same identity `winapp run` registered)
winapp unregister counter.cs

# Or remove it as soon as the app exits
winapp run counter.cs --unregister-on-exit

winapp unregister counter.cs ne nécessite aucun chemin de manifeste : il évalue les valeurs du #:property fichier de la même façon run et supprime uniquement un package inscrit à partir de la sortie de build de ce fichier. Une application nommée identique inscrite à partir d’un autre dossier est refusée, sauf si vous passez --force. Si l’exécution a utilisé une option qui forme l’identité ou la disposition, passez la même option à unregister:

winapp run counter.cs -p WinAppPackageName=com.contoso.alt
winapp unregister counter.cs -p WinAppPackageName=com.contoso.alt

winapp run counter.cs -c Release --arch arm64
winapp unregister counter.cs -c Release --arch arm64

-p remplace les propres directives du fichier, et une Directory.Build.props autre .cs clé WinAppPackageName peut être désactivée $(Configuration) ou $(RuntimeIdentifier) , par conséquent, chacune d’entre elles peut modifier le package qui est inscrit.

Une fois que la sortie temporaire du Kit de développement logiciel (SDK) a été nettoyée, winapp unregister counter.cs ne peut plus confirmer que l’inscription provient de ce fichier et l’ignorera , utilisez winapp unregister --prune pour effacer les inscriptions dont les fichiers ont disparu ou --force pour supprimer un fichier spécifique de toute façon. Si l’exécution utilisée --output-appx-directory, passez le même répertoire pour unregister qu’il puisse reconnaître la disposition.

La même chose s’applique à un chemin de sortie personnalisé : la propriété est confirmée à partir de la disposition standard <root>\bin\<configuration> du Kit de développement logiciel (SDK), de sorte qu’une exécution générée ne -p OutputPath=<somewhere-else> peut pas être mise en correspondance avec son fichier source. unregister ignore plutôt que de deviner un répertoire plus large : nommez la disposition avec --output-appx-directory, ou utilisez --force.

Exemples à fichier unique :

# Build and run a file-based app with package identity
winapp run counter.cs

# Register identity without launching (e.g. to attach Visual Studio)
winapp run counter.cs --no-launch

# Release build, detached, printing the PID as JSON
winapp run counter.cs -c Release --detach --json

# Capture OutputDebugString output and crash diagnostics
winapp run counter.cs --debug-output

# Forward arguments to the app
winapp run counter.cs -- --verbose --input data.json

# Wipe the app's LocalState and start fresh
winapp run counter.cs --clean

# Remove the package it registered
winapp unregister counter.cs

Note

L’identité par défaut inclut un court hachage du chemin d’accès du fichier , counter.cs de counter-a1b2c3d4 sorte que deux counter.cs fichiers dans différents dossiers sont des applications différentes et conservent leurs propres paramètres et LocalState. Le hachage est dérivé du chemin d’accès. Il survive donc aux modifications et réexécrive et ne change que si vous déplacez le fichier. Définir #:property WinAppPackageName=<name> pour choisir une identité stable vous-même ; il est normalisé à ce qui Identity/@Name permet — les caractères en dehors [-.A-Za-z0-9] sont supprimés, les noms inférieurs à 3 caractères sont rembourrés avec 1, et le résultat est limité à 50 caractères, de sorte My App que les registres comme MyApp. Dans les deux cas, le menu Démarrer et les paramètres affichent votre WinAppDisplayName (par défaut : le nom du fichier), et non l’identité. L’identité est toujours étendue à votre compte d’utilisateur, de sorte qu’elle ne se heurte jamais à un autre utilisateur sur le même ordinateur.

Propriétés MSBuild (package NuGet) :

Lorsque vous utilisez le package NuGet Microsoft.Windows.SDK.BuildTools.WinApp, dotnet run appelle automatiquement winapp run.

Tout ce qui est écrit après dotnet run est passé à votre application, exactement comme il le serait sans le package. Configurez le lanceur avec les propriétés MSBuild ci-dessous :

# Goes to your app. `--` is optional here, but required when the flag is also a
# `dotnet run` option (--configuration, --framework, --project, -c, -f, -r, ...),
# otherwise the SDK claims it and your app never sees it.
dotnet run --devtools
dotnet run -- --devtools
dotnet run -- --configuration Release

# Configures WinApp; --devtools still reaches your app
dotnet run -p:WinAppRunDetach=true --devtools

Les propriétés MSBuild suivantes peuvent être définies dans votre .csproj pour contrôler le comportement :

Propriété Default Description
EnableWinAppRunSupport true Activer/désactiver la fonctionnalité de prise en charge de l’exécution
WinAppLaunchArgs (vide) Arguments à transmettre à l’application lors du lancement
WinAppRunUseExecutionAlias déduit de l’application Lancez via l’alias d’exécution au lieu de l’activation AUMID. Non défini, winapp l’déduit : une application console utilise un alias afin que sa sortie atteigne le terminal, une application fenêtré utilise AUMID. Définissez true ou false décidez-le vous-même.
WinAppRunNoLaunch false Inscrire uniquement l’identité sans lancer
WinAppRunDebugOutput false Capturez des OutputDebugString messages et des exceptions de première chance. Un seul débogueur peut s’attacher à la fois (empêche VS/VS Code). Utilisez WinAppRunNoLaunch plutôt pour attacher un autre débogueur.
WinAppRunDetach false Retournez immédiatement après le lancement au lieu d’attendre la fermeture de l’application. Imprime le PID.
WinAppRunUnregisterOnExit false Désinscrire le package de développement après la fermeture de l’application
WinAppRunClean false Supprimer les données d’application du package existant (LocalState, paramètres) avant le redéploiement
WinAppRunSymbols false Téléchargez des symboles à partir du serveur de symboles Microsoft pour une analyse de blocage native plus riche. Seul a un effet avec WinAppRunDebugOutput.
WinAppRunExecutable (vide) Chemin d’accès exécutable relatif au dossier build-output. Utilisez lorsque le manifeste contient $targetnametoken$ et que le dossier de sortie a plusieurs .exe.
WinAppRunArgs (vide) Arguments bruts ajoutés à la winapp run ligne de commande, pour les options sans propriété dédiée (par exemple --verbose). Ajouté après chaque propriété ci-dessus.

Paramètres mutuellement exclusifs. WinAppRunNoLaunch et WinAppRunDetach chacun décrivent un comportement de lancement différent, de sorte qu’ils entrent en conflit avec les autres propriétés de lancement et entre eux. La définition d’une paire en conflit échoue avec --X and --Y cannot be used together:

Propriété Impossible de combiner avec
WinAppRunNoLaunch WinAppRunDetach, WinAppRunDebugOutput, WinAppRunUnregisterOnExit
WinAppRunDetach WinAppRunNoLaunch, WinAppRunDebugOutput, WinAppRunUnregisterOnExit

WinAppRunUseExecutionAlias n’est délibérément pas dans cette liste, dans les deux sens. false demande l’activation AUMID, qui n’est pas lancée et détache déjà utilisée ; true n’est tout simplement pas appliqué lorsque l’un ou l’autre est défini, car un alias d’exécution a besoin d’un processus suivi et en cours d’exécution. Ainsi, un projet qui s’exécute <WinAppRunUseExecutionAlias>true</WinAppRunUseExecutionAlias> toujours correctement sous dotnet run -p:WinAppRunDetach=true, le lancement via AUMID plutôt que l’échec.

WinAppRunUseExecutionAlias, WinAppRunDebugOutputet WinAppRunUnregisterOnExit peut être combiné les uns avec les autres. WinAppRunClean, WinAppRunSymbols, WinAppRunExecutableet WinAppLaunchArgs n’ont aucune restriction. WinAppRunArgs n’ajoute aucune restriction de sa propre, mais un commutateur passé à travers il est vérifié comme n’importe quel autre, donc WinAppRunArgs="--detach" toujours en conflit avec WinAppRunNoLaunch.

<PropertyGroup>
  <WinAppRunUseExecutionAlias>true</WinAppRunUseExecutionAlias>
  <WinAppRunDebugOutput>true</WinAppRunDebugOutput>
</PropertyGroup>

Unregister

Annulez l’inscription d’un package de développement chargé de manière indépendante. Supprime uniquement les packages inscrits en mode de développement (par exemple, via winapp run ou create-debug-identity). Les packages installés dans le Magasin ou MSIX ne sont jamais supprimés.

winapp unregister [input] [options]

Arguments :

  • input- Chemin d’un .NET application basée sur un fichier (un seul.cs) dont le package doit être désinscrit. Son identité est résolue de la même façon : winapp run à partir d’un manifeste créé si l’application en a une, sinon à partir de ses #:property valeurs, aucun chemin de manifeste n’est nécessaire. Omettez d’utiliser --manifest ou de détecter automatiquement un manifeste dans le répertoire actif. Impossible de combiner avec --manifest, qui nomme le package de manière différente et peut être résolu en un autre.

Options :

  • --manifest <path> - Chemin d’accès à Package.appxmanifest (par défaut : détection automatique à partir du répertoire actif)
  • --force - Pour l’annulation de l’inscription locale uniquement, ignorez la vérification du répertoire d’emplacement d’installation et annulez l’inscription même si le package a été inscrit à partir d’une autre arborescence de projet. Il est rejeté avec --on; les vérifications de propriété cible ne peuvent pas être ignorées.
  • --on <target> - Supprimez l’inscription de développement winapp correspondante de sandbox, et non de cette machine. Nécessite un manifeste et ne prend pas en charge --force. Consultez le nettoyage de l’application bac à sable.
  • --prune - Supprimez chaque inscription en mode développement dont les fichiers ont disparu. Impossible de combiner avec une entrée, , --manifest, --property--configuration, --arch, , --runtimeou --output-appx-directory.
  • -p, --property <Name=Value> - Propriété MSBuild utilisée lors de la résolution de l’identité d’une application basée sur un .cs fichier. Répétable. Transmettez les mêmes propriétés affectant l’identité que l’exécution utilisée (par exemple -p WinAppPackageName=...), car une propriété de ligne de commande remplace les propres #:property directives du fichier. S’applique uniquement à une .cs entrée.
  • -c, --configuration <name> - Configuration de build utilisée lors de la résolution de l’identité d’une application basée sur des .cs fichiers. Valeur par défaut : Debug. Transmettez la même configuration que l’exécution utilisée : un Directory.Build.props à côté de la .cs zone peut être définie WinAppPackageName ou WinAppManifestPath conditionnellement sur $(Configuration). S’applique uniquement à une .cs entrée.
  • --arch <x64|arm64|x86> - Architecture cible utilisée lors de la résolution de l’identité d’une application basée sur des .cs fichiers. Valeur par défaut : architecture de processus actuelle. Transmettez la même architecture que celle utilisée, car l’identité peut également être désactivée $(RuntimeIdentifier). S’applique uniquement à une .cs entrée.
  • -r, --runtime <rid>- Ciblez .NET identificateur d'exécution (par exemplewin-x64) utilisé lors de la résolution de l'identité d'une application basée sur des .cs fichiers. Seule son architecture est utilisée, et elle remplace --arch. S’applique uniquement à une .cs entrée.
  • --output-appx-directory <path> - Répertoire de disposition AppX à partir duquel le package a été inscrit. Nécessaire uniquement lorsque l’exécution est utilisée --output-appx-directory, car rien sur les enregistrements de package qui exécute l’option d’exécution a produit sa disposition.
  • --json - Mettre en forme la sortie en tant que JSON

Résultat :

  • Détermine le nom du package , à partir de l’identité .cs résolue du fichier ou en lisant le manifeste
  • Recherche les deux {name} et {name}.debug les packages (la variante de débogage est créée par create-debug-identity)
  • Vérifie que chaque package a été inscrit en mode de développement (IsDevelopmentMode == true)
  • Vérifie que le package appartient à l’application que vous avez nommée (sauf --force) : son emplacement d’installation doit se trouver sous un répertoire que vous avez identifié : la .cs sortie de build du fichier, le répertoire du manifeste, le répertoire actif ou un répertoire explicite --output-appx-directory. Un package dont l’emplacement d’installation ne peut pas être résolu (ses fichiers ont été supprimés) est ignoré, car l’identité seule n’est pas une preuve de propriété : deux applications qui définissent #:property WinAppPackageName=counter tous deux l’inscription de la même identité à partir de différents dossiers. Permet --prune d’effacer les inscriptions dont les fichiers sont disparus.
  • Désinscrit les packages correspondants

Nettoyage des inscriptions mortes (--prune) :

Une inscription dépasse ses fichiers. Supprimez une sortie de build, une arborescence de projet ou (pour une application basée sur un fichier) laissez Windows nettoyer%LOCALAPPDATA%\Temp, et le package reste inscrit : Windows conserve l’identité et son entrée de menu Démarrer, mais l’activation ne fait rien en mode silencieux. Ceux-ci s’accumulent de façon invisible.

# List dev registrations whose files are gone, then confirm before removing
winapp unregister --prune

# Skip the prompt (required for non-interactive/CI use)
winapp unregister --prune --force

Seules les inscriptions en mode développement sont prises en compte et chacune est supprimée par son nom de package complet. Par conséquent, un package nommé identique installé à partir d’un emplacement actif n’est pas touché. L’invite existe, car un emplacement d’installation manquant est généralement un dossier supprimé, mais décrit également un package inscrit à partir d’un partage réseau déconnecté ou d’un lecteur amovible. Passez en revue la liste avant de confirmer.

Exemples :

# Unregister from current directory (auto-detects manifest)
winapp unregister

# Unregister a .NET file-based app by its source file
winapp unregister counter.cs

# Unregister with explicit manifest
winapp unregister --manifest ./Package.appxmanifest

# Force unregister even if registered from a different project tree
winapp unregister --force

# Remove every dev registration whose files are gone
winapp unregister --prune

# JSON output for scripting
winapp unregister --json

cert

Générez, inspectez et installez des certificats de développement.

Générer un certificat

Générez des certificats de développement pour la signature de paquet.

winapp cert generate [options]

Options :

  • --manifest <Package.appxmanifest>- Extrayez le certificat publisher à partir du manifesteIdentity/@Publisher. Seul l’éditeur est requis. Par conséquent, un manifeste partiellement complet fonctionne toujours. Si le manifeste n’a pas d’éditeur utilisable, la commande échoue au lieu de remplacer une valeur par défaut. Par conséquent, le certificat ne peut jamais ne pas être compatible silencieusement avec le manifeste.
  • --publisher <name>- Publisher pour le certificat. Lors de la génération d’un certificat, cette option est prioritaire --manifestsur ; une valeur explicitement vide échoue au lieu d’utiliser l’éditeur de manifeste. Accepte un nom unique X.500 complet (par exemple CN=Contoso, O=Contoso Ltd, C=US) ou un nom nu qui est automatiquement encapsulé en tant que CN=<name>. Les composants doivent être séparés par des virgules et une valeur unique ; Les rdn à valeurs multiples (CN=Foo+OU=Bar) et les barres obliques inverses ne sont pas pris en charge, car l’éditeur de manifeste MSIX ne peut pas les représenter. Un nom unique mal formé (par exemple CN= , ou CN=A,,O=B) est rejeté avec une sortie non nulle et une erreur nommant le problème, plutôt que de produire un certificat qui ne peut jamais correspondre à l’éditeur de manifeste.
  • --output <path> - Chemin d’accès au fichier de certificat de sortie (prend en charge les chemins absolus et relatifs)
  • --password <password> - Mot de passe de certificat (par défaut : password, qui est publiquement connu - voir sortie JSON et sécurité)
  • --valid-days <valid-days> - Nombre de jours pendant lesquels le certificat est valide (valeur par défaut : 365)
  • --install - Installer le certificat dans le magasin d’ordinateurs local après la génération
  • --if-exists <Error|Overwrite|Skip> - Définir le comportement si le fichier de certificat existe déjà (valeur par défaut : Erreur)
  • --export-cer - Exportez un .cer fichier (clé publique uniquement) en même temps que le .pfxfichier . Utile pour distribuer le certificat public séparément pour l’installation d’approbation.
  • --json - Mettre en forme la sortie au format JSON pour la consommation par programmation. Les erreurs sont également retournées en tant que JSON ({"error": "..."}).

Sortie JSON :

{
  "certificatePath": "C:\\app\\devcert.pfx",
  "password": "password",
  "defaultPasswordIsPublic": true,
  "publisher": "Contoso",
  "subjectName": "CN=Contoso",
  "warnings": [
    "Protected with the default password ('password'), which is public. Treat this certificate as development-only: anyone who obtains the .pfx can sign as you. Pass --password to choose your own, and use a CA-issued certificate or Azure Trusted Signing to ship."
  ],
  "skipped": false
}

publisher est le nom complet et subjectName le nom unique complet sur lequel le certificat a été émis. defaultPasswordIsPublic est toujours présent lorsqu’un certificat est généré. Quand c’est truele cas, il .pfx est protégé par un mot de passe que tout le monde peut deviner. Par conséquent, le certificat doit signer uniquement les builds qui restent sur vos propres ordinateurs . Vérifiez-le avant qu’un script n’ait la main sur quoi que ce soit d’autre. warnings porte la même divulgation que le texte et est omis lorsqu’il n’y a rien à signaler. publicCertificatePath s’affiche uniquement avec --export-cer.

Avec --if-exists skip, lorsque le fichier de certificat existe déjà, la commande la laisse intacte et retourne uniquement son chemin d’accès :

{
  "certificatePath": "C:\\app\\devcert.pfx",
  "skipped": true
}

Vérifiez skipped avant de lire les autres champs. Pour inspecter le certificat existant, exécutez winapp cert info.

Informations sur le certificat

Afficher les détails du certificat à partir d’un fichier PFX ou CER. Utile pour vérifier qu’un certificat correspond à votre manifeste avant la signature.

winapp cert info <cert-path> [options]

Arguments :

  • cert-path - Chemin d’accès au fichier de certificat (PFX ou CER)

Options :

  • --password <password> - Mot de passe pour le fichier PFX, ignoré pour une cer publique (par défaut : « mot de passe »)
  • --json - Mettre en forme la sortie en tant que JSON

Installation du certificat

Installez le certificat dans le magasin de certificats de l’ordinateur.

winapp cert install <cert-path> [options]

Arguments :

  • cert-path - Chemin d’accès au fichier de certificat à installer

Exemples :

# Generate certificate for specific publisher
winapp cert generate --publisher "CN=My Company" --output ./mycert.pfx

# Generate certificate and export public key .cer file
winapp cert generate --publisher "CN=My Company" --export-cer

# Generate certificate with JSON output (for scripting)
winapp cert generate --publisher "CN=My Company" --json

# View certificate details
winapp cert info ./mycert.pfx

# View certificate details as JSON
winapp cert info ./mycert.pfx --json

# Install certificate to machine
winapp cert install ./mycert.pfx

Signe

Signer des packages MSIX et des exécutables avec des certificats.

winapp sign <file-path> <cert-path> [options]

Arguments :

  • file-path - Chemin d’accès au package MSIX ou exécutable à signer
  • cert-path - Chemin d’accès au certificat de signature (.pfx)

Options :

  • --password <password> - Mot de passe du certificat (par défaut : « mot de passe »)
  • --timestamp <url> - URL du serveur d’horodatage RFC 3161

Exemples :

# Sign MSIX package
winapp sign MyApp.msix ./mycert.pfx

# Sign executable with a non-default certificate password
winapp sign ./bin/MyApp.exe ./mycert.pfx --password mypassword

az-sign

Signez un fichier (exe, MSIX ou MSIX bundle) à l’aide de Signatures de confiance Azure : une identité de signature gérée par le cloud, donc aucune clé privée (PFX) ne vit jamais sur l’ordinateur local.

winapp az-sign <file-path> [options]

Arguments :

  • file-path - Chemin d’accès au fichier à signer (exe, msix ou msixbundle)

Options :

  • --subscription, - -s Azure ID d’abonnement à utiliser. S’il n’existe pas et que plusieurs abonnements existent, vous serez invité à le faire
  • --resource-group, -r - Groupe de ressources pour limiter les comptes de signature
  • --account - Nom du compte de signature. Doit être utilisé avec --resource-group
  • --profile, - -p Nom du profil de certificat. Doit être utilisé avec --account
  • --metadata-file, - -m Chemin d’accès à un objet existant metadata.json. Ignore la découverte des ressources et les invites de sélection de compte/profil et signe directement. Les informations d’identification de Azure non interactives doivent déjà être disponibles ; l’interface CLI peut sinon revenir à une invite de locataire interactive ou az login, mais l’API programmatique npm est toujours non interactive et échoue au lieu d’inviter

Authentification :

az-signutilise la chaîne d'informations d'identification standard de Azure (DefaultAzureCredential). Pour CI/CD, définissez AZURE_TENANT_IDet AZURE_CLIENT_IDAZURE_CLIENT_SECRET (ou utilisez GitHub Actions identité managée/ OIDC). Une session Azure CLI existante (az loginy compris l’action azure/login de GitHub) est également respectée dans n’importe quel environnement. Uniquement quand aucune information d’identification n’est trouvée et que la session est interactive s’ouvre az-signaz login pour vous.

Configuration requise :

  • Un compte de signature de code Azure et un profil de certificat (créé dans le portail Azure après la validation de l’identité), ainsi que le rôle signataire du profil de certificat de signature de code affecté à votre identité. Pour plus d’informations, consultez Azure documentation de démarrage rapide sur la signature d’artefacts.
  • Un runtime x64 à l’échelle de l’ordinateur .NET 8 (ou version ultérieure) installé. La bibliothèque de client de signature Azure est un assembly managé qui signtool.exe se charge dans un processus distinct ; le runtime autonome de winapp ne le satisfait pas. Installez-le en cas d’échec de https://dotnet.microsoft.com/download la signature avec une erreur de chargement du runtime.
  • Redistribuable Visual C++ (x64) Microsoft. La Azure bibliothèque de client de signature dépend du runtime VC++ et, étant donné que winapp télécharge le package NuGet brut plutôt que le programme d’installation officiel des outils clients, cette dépendance n’est pas installée automatiquement. Une machine propre peut échouer même avec .NET et SignTool présents. Installez la dernière version redistribuable x64 en cas d’échec de https://aka.ms/vs/17/release/vc_redist.x64.exe la signature avec une 0xc000007berreur « L’application n’a pas pu démarrer correctement » ou une erreur DLL manquante à partir du dlib.

CI avec privilèges minimum : La découverte automatique (liste des abonnements, groupes de ressources, comptes et profils) a besoin d’un accès en lecture dans une étendue parente. Pour éviter chaque appel de référencement de collection, passez les quatre --subscriptionappels --resource-group--account, puis --profileaz-sign validez le compte et le profil avec des lectures de ressources directes (un GET sur chaque ressource nommée) au lieu d’énumérer la collection parente, de sorte qu’un principal limité à ce compte et à ce profil suffit. Omettre l’un d’entre eux réintroduira un appel de référencement ( par exemple, en laissant la --subscription liste des az-sign abonnements auxquels votre identité peut accéder), ce qu’un principal limité peut ne pas être autorisé à effectuer. Un principal limité à un seul profil de certificat peut ignorer entièrement la validation en transmettant un point de terminaison de compte et un profil prégéné ( --metadata-file qui spécifie directement le point de terminaison et le profil du compte).

Exemples :

# Interactive — discover/select subscription, account, and profile
winapp az-sign ./app.msix

# Fully specified — no prompting (ideal for CI/CD)
winapp az-sign ./app.msix --subscription <sub-id> --resource-group <rg> --account <account> --profile <profile>

# Reuse an existing metadata.json (skips resource discovery and selection; authentication may still prompt)
winapp az-sign ./app.msix --metadata-file ./metadata.json

create-external-catalog

Générez un CodeIntegrityExternal.cat fichier catalogue contenant des hachages de fichiers exécutables à partir de répertoires spécifiés. Ce catalogue est utilisé avec l’indicateur TrustedLaunch dans les manifestes de package partiellement alloués MSIX (AllowExternalContent) pour autoriser l’exécution de fichiers externes non inclus dans le package lui-même.

Cela est similaire à la façon de signtool.exe créer AppxMetadata\CodeIntegrity.cat lors de la signature d’un package MSIX, mais génère un catalogue externe à utiliser avec l’empaquetage d’emplacement éparse/externe.

winapp create-external-catalog <input-folder> [options]

Arguments :

  • input-folder - Un ou plusieurs répertoires contenant des fichiers exécutables à traiter. Séparer plusieurs répertoires avec des points-virgules (par exemple, "dir1;dir2")

Options :

  • --recursive, - -r Inclure des fichiers à partir de sous-répertoires
  • --use-page-hashes - Inclure des hachages de page lors de la génération du catalogue (produit un catalogue plus grand avec des données de hachage par page)
  • --compute-flat-hashes - Inclure des hachages de fichiers plats lors de la génération du catalogue
  • --if-exists <Error|Overwrite|Skip> - Comportement lorsque le fichier de sortie existe déjà (valeur par défaut : Error)
  • --output, -o - Chemin d’accès du fichier catalogue de sortie. S’il n’est pas spécifié, CodeIntegrityExternal.cat est créé dans le répertoire actif. Si un répertoire est spécifié, le nom de fichier par défaut est ajouté.

Résultat :

  • Analyse les répertoires spécifiés pour les fichiers exécutables (fichiers binaires PE avec sections de code)
  • Génère un fichier de définition de catalogue (CDF) avec des hachages de tous les exécutables trouvés
  • Utilise Windows API CryptoCAT pour produire le fichier catalogue .cat
  • Les fichiers non exécutables (par exemple, .txt.dll sans sections de code) sont automatiquement ignorés

Exemples :

# Generate catalog for all executables in a directory
winapp create-external-catalog ./bin

# Include files in subdirectories
winapp create-external-catalog ./bin --recursive

# Specify a custom output path
winapp create-external-catalog ./bin --output ./dist/CodeIntegrityExternal.cat

# Overwrite existing catalog
winapp create-external-catalog ./bin --if-exists Overwrite

# Skip generation if catalog already exists
winapp create-external-catalog ./bin --if-exists Skip

# Include page hashes (for stricter code integrity validation)
winapp create-external-catalog ./bin --use-page-hashes

# Process multiple directories
winapp create-external-catalog "./bin;./lib" --recursive

# Combine multiple options
winapp create-external-catalog ./bin --recursive --use-page-hashes --compute-flat-hashes --output ./dist/CodeIntegrityExternal.cat --if-exists Overwrite

Quand utiliser :

Utilisez cette commande lors de la création d’un package MSIX partiellement alloué qui utilise TrustedLaunch pour vérifier les exécutables externes. Le flux de travail classique est le suivant :

  1. winapp manifest generate --template sparse — Créer un manifeste partiellement alloué avec AllowExternalContent
  2. winapp create-external-catalog ./bin — Générer le catalogue d’intégrité du code pour les exécutables de votre application
  3. winapp pack — Empaqueter le manifeste, les ressources et le catalogue dans un fichier MSIX

Outil

Accédez directement aux outils du Kit de Développement Logiciel (SDK) Windows. Utilise les outils disponibles dans Microsoft.Windows. SDK. BuildTools

winapp tool <tool-name> [tool-arguments]

Outils disponibles :

  • makeappx - Créer et manipuler des packages d’application
  • signtool - Signer des fichiers et vérifier les signatures
  • mt - Outil manifeste pour les assemblages côte-à-côte
  • Et d’autres outils Windows SDK de Microsoft.Windows. SDK. BuildTools

Exemples :

# Use signtool to verify signature
winapp tool signtool verify /pa MyApp.msix

Vérification de signature

Les outils de génération sont téléchargés à partir de NuGet, puis exécutés, de sorte que winapp vérifie chacun d’eux pour obtenir une signature Microsoft Authenticode valide immédiatement avant de l’exécuter. Le certificat doit nommer Microsoft Corporation comme organisation de signature. Cela s’applique à chaque commande qui s’exécute à un outil sdk, y compris tool, packageet sign. Un outil qui échoue à la vérification n’est pas exécuté :

'mt.exe' is not validly signed by Microsoft, so it was not run (C:\...\mt.exe).

Un échec ici signifie que le fichier sur le disque n’est pas ce qui Microsoft publié , le plus souvent un téléchargement endommagé ou partiel. Supprimez le package du cache NuGet et réexécutez la commande pour que winapp le télécharge à nouveau.

winapp conserve ensuite l’outil ouvert tant qu’il s’exécute, de sorte que le fichier qu’il a vérifié est le fichier Windows se charge. S’il ne peut pas contenir l’outil en place, il n’est pas exécuté non plus :

'mt.exe' could not be held open for verification, so it was not run (C:\...\mt.exe).

Fermez tout ce qui utilise le fichier ( une analyse antivirus ou un éditeur ouvert est la cause habituelle) et réexécutez la commande. Si l’outil est passé plutôt qu’en cours d’utilisation, supprimez le package du cache NuGet afin que winapp le télécharge à nouveau.


store

Exécutez une commande CLI développeur du Microsoft Store. Cette commande télécharge l’interface CLI Microsoft Store développeur si elle n’est pas déjà téléchargée. En savoir plus sur l’interface CLI Microsoft Store Developer CLI.

winapp store [args...]

Arguments :

Résultat :

  • Vérifie que l’interface CLI Microsoft Store Développeur (msstore) est téléchargée et disponible sur votre système.
  • Transfère tous les arguments à l’interface msstore CLI.
  • Exécute la commande montrant la sortie directement dans votre terminal.

Exemples :

# List all apps in your Microsoft Partner Center account
winapp store app list

# Publish a package to the Microsoft Store
winapp store publish ./myapp.msix --appId <your-app-id>

get-winapp-path

Obtenir les chemins d’accès aux composants du Kit de développement logiciel (SDK) Windows installés.

winapp get-winapp-path [options]

Ce qu’il retourne :

  • Chemins d’accès au répertoire de l’espace .winapp de travail
  • Répertoires d’installation de package
  • Emplacements d’en-tête générés

target

Exécutez des commandes, copiez des fichiers, inspectez l’état ou capturez l’ensemble du bureau invité.

Chaque verbe prend sandbox comme premier argument. À l’exception de snapshot, ces commandes peuvent préparer ou démarrer le bac à sable. Consultez Windows exécution de bac à sable pour connaître les prérequis, les autorisations, le cycle de vie et la récupération.

target exec

Exécutez une commande en tant qu’utilisateur invité.

winapp target exec <target> [--cwd <path>] [--json] -- <executable> [arguments...]
winapp target exec sandbox -- dotnet --info

Arguments après -- conservation de leurs limites. Les flux standard et le code de sortie du processus invité sont transférés ; ce n’est pas un terminal complet. --json met en forme les échecs winapp sur stderr sans modifier le stdout de la commande enfant. Utilisez la structure error.code pour distinguer un échec cible de l’état de sortie d’une application.

Un groupe également explicite WINAPP_UI_WORKFLOW_ID d’appels d’interface utilisateur invité effectués par la commande ; consultez la coordination de l’interface utilisateur du bac à sable.

push cible et extraction cible

Copiez un fichier ou un répertoire dans la direction nommée par le verbe.

winapp target push <target> <host-source> <target-destination> [--json]
winapp target pull <target> <target-source> <host-destination> [--json]
winapp target push sandbox .\setup.ps1 Setup\setup.ps1
winapp target pull sandbox Results .\results

Les chemins cibles sont relatifs à la zone de travail gérée de la cible ; les chemins cibles absolus, rootés et UNC sont rejetés. Une destination de fichier inclut son nom de fichier. Consultez Commandes en cours d’exécution et copie de fichiers pour la disposition du répertoire, la gestion des liens et l’exécution d’un script copié.

instantané cible

Préparation des rapports, déploiements et fenêtres invitées sans démarrer un bac à sable.

winapp target snapshot <target> [--json]
winapp target snapshot sandbox

Il ne reconnecte pas un client ou ne répare pas un agent. Aucun bac à sable en cours d’exécution n’est un résultat réussi, pas une erreur. Consultez Inspecting the Sandbox for interpreting readiness and process IDs.

capture d’écran cible

Capturez le bureau invité à sa taille de pixel native en tant que PNG hôte, sans sélecteur d’application ou bordures de fenêtre hôte. --json signale l’origine des coordonnées invitées.

winapp target screenshot <target> [-o <host-path>] [--json]
winapp target screenshot sandbox -o .\sandbox.png

Utilisez ui screenshot --on sandbox -a <app> plutôt une fenêtre d’application. Consultez captures d’écran et enregistrements pour connaître les exigences du client, les limitations de focus et la gestion des sorties.

enregistrement cible

Enregistrez le bureau invité sur H.264 MP4. Les fichiers vidéo et frame hôtes arrivent une fois l’enregistrement terminé ; JSON et le manifeste de trame décrivent toute mise à l’échelle ou remplissage.

winapp target record <target> [-o <host-path>] [--duration-sec <n>] [--fps <n>] [--max-edge <px>] [--frames] [--overwrite] [--json]
winapp target record sandbox -o .\sandbox.mp4 --duration-sec 20 --fps 15

Utilise la durée, l’image, le remplacement et les options de résultat de ui record, mais capture le bureau plutôt qu’une application. Préférez une utilisation positive --duration-sec de l’interface CLI sans assistance ; l’assistance npm nécessite durationSec. Consultez la capture de bac à sable pour obtenir des preuves partielles et des échecs de préparation à la capture.


find-ui

Agent-first. find-ui est conçu principalement pour les agents de codage IA : il permet à un agent d’extraire le balisage WinUI réel, de compiler le balisage WinUI à partir des galeries d’expédition au lieu de l’inventer, et --json rend chaque résultat (et chaque échec) lisible par l’ordinateur. Il fonctionne tout aussi bien tapé à la main.

Recherchez des contrôles et des exemples WinUI pour obtenir un exemple de code de travail. WinUI uniquement : le corpus est la galerie WinUI 3 et la Windows Community Toolkit (ainsi que quelques modèles principaux organisés) : il ne couvre pas WPF, WinForms ou d’autres frameworks d’interface utilisateur. Une troisième source, microsoft-ui-reactor ReactorGallery, est opt-in : elle est exclue d’une recherche normale et uniquement recherchée lorsque vous passez (ses exemples déclaratifs --source reactor C#uniquement ne collent pas dans une application XAML standard, donc contactez-le uniquement lors de la création d’un projet Reactor/MVU).

winapp find-ui "<query>" [options]

La galerie, le kit de ressources et l’expédition de l’corporatation Reactor à l’intérieur de l’interface CLI ne fonctionne donc find-ui pas avec aucun accès réseau, y compris lors d’une première exécution dans un bac à sable d’agent ou derrière un proxy d’entreprise qui bloque raw.githubusercontent.com. Lorsque GitHub est accessible, l’interface CLI s’actualise et met en cache le résultat par utilisateur sous <global .winapp>/cache/find-ui; le corpus intégré n’est qu’un plancher, jamais un plafond. Les données mises en cache sont actualisées au maximum toutes les 24 heures ou à la demande avec --refresh.

Le corpus intégré est récupéré à partir de GitHub chaque fois qu’une version stable est générée et qu’une actualisation qui échoue arrête la build de mise en production plutôt que d’expédier silencieusement des données plus anciennes , le baker extrait via le même chemin --refresh de code utilise, de sorte qu’une défaillance signifie que l’actualisation en direct est interrompue également et vaut la peine d’examiner avant l’expédition. Une version peut toujours être coupée par rapport au corpus précédemment validé, mais uniquement comme remplacement explicite. Lorsque les résultats sont servis "corpus": "embedded" à partir de la copie intégrée de la galerie/kit de ressources/corps de réacteur, find-ui indique que sur stderr et --json la sortie porte (d’autres valeurs : "network" pour une nouvelle extraction, "cache" pour le cache local). Une requête principale uniquement ( --source coreou un --id ensemble qui est tous les modèles de base ) signale "embedded" également, car les modèles principaux organisés sont compilés dans l’interface CLI et ne sont jamais extraits ; il n’affiche aucune notification d’obsolescence, car --refresh ne peut pas les modifier. Le corpus champ est signalé chaque fois que les résultats ont été servis ; il est absent uniquement quand aucun corpus n’a pu être chargé du tout.

Options :

  • --id <id> - Récupérer le code (Gallery/Toolkit retourne XAML et/ou C# ; Reactor est C#-only) ainsi que les notes requises pour un ou plusieurs ID de scénario à partir d’une recherche antérieure (par exemple gallery-tabview-1). Répétable. Les ID ne respectent pas la gallery-tabview-1casse . GALLERY-TABVIEW-1
  • --list - Répertoriez chaque id de contrôle/d’exemple détectable au lieu de rechercher (Galerie + Kit de ressources + cœur ; la source d’opt-in Reactor est exclue).
  • --source <gallery|toolkit|reactor|core> - Restreindre les résultats de la recherche à une seule source. (Recherche uniquement - non valide avec --list/--id.) Reactor est opt-in - il est exclu d’une recherche normale, c’est --source reactor donc la seule façon de la rechercher.
  • --max <N> - Nombre maximal de contrôles mis en correspondance à retourner (valeur par défaut : 3). S’applique uniquement à la recherche ; ignoré avec --list/--id.
  • --refresh- Ignorez le cache local et récupérez à nouveau le corpus WinUI à partir de GitHub.
  • --json - Émettre un JSON structuré (convivial pour l’agent). Pour la recherche, chaque correspondance porte source, , scorecontrol, descriptionet un scenarios tableau dont les entrées contiennent le scénario id et header; pour --id, le code complet. Sous --jsonchaque échec , y compris les erreurs d’argument/d’analyseur, telles qu’un non-entier --max , est émise en tant qu’objet plat {"error": "..."} sur stdout avec un code de sortie non nul, de sorte que la sortie reste lisible par l’ordinateur.

Flux de travail : recherchez compactement le contrôle approprié et ses ID de scénario, puis récupérez le code complet pour obtenir la meilleure correspondance avec --id.

Exemples :

# Find a control by intent (compact results with scenario ids)
winapp find-ui "tabbed layout"

# Restrict to the Windows Community Toolkit
winapp find-ui "settings card" --source toolkit

# Restrict to Reactor (opt-in; C#-only declarative WinUI — Reactor projects only)
winapp find-ui "flex layout" --source reactor

# Fetch the full XAML + C# for a specific scenario
winapp find-ui --id gallery-tabview-1

# Agent-friendly structured output
winapp find-ui "color picker" --json

# Browse everything, or force a corpus refresh
winapp find-ui --list
winapp find-ui "navigation view" --refresh

Connexe :find-ui recherche des exemples WinUI ; permet find-api de rechercher l’aire d’API (types, membres, énumérations) d’un projet et winapp ui search de rechercher l’arborescence de l’interface utilisateur d’une application en cours d’exécution .


find-api

Agent-first. find-api est conçu principalement pour les agents de codage d’IA : il a pour effet de créer du code généré dans l’API, un projet fait réellement référence au lieu de la mémoire du modèle, et --json plus des codes de sortie non nuls sur les symboles manquants permettent à un agent de codegen de porte sur la réponse. Il fonctionne tout aussi bien tapé à la main.

Recherchez et inspectez l’aire d’API Windows/WinRT (types, membres, énumérations, espaces de noms) disponibles pour un projet, résolu à partir de ses métadonnées référencées.winmd/.dll. Les recherches nues de formulaire ; Les sous-verbes explorent un type spécifique, un espace de noms ou l’index lui-même.

winapp find-api "<query>" [options]
winapp find-api [command] [options]

L’index est généré à partir des packages NuGet/SDK restaurés du projet (via project.assets.json) lors de la première utilisation et actualisé automatiquement lorsque le projet est restauré. Il vit sous le cache global .winapp (cache/find-api/) et est partagé entre les projets. Restaurez le projet en premier (winapp restore ou dotnet restore).

Chaque correspondance est répertoriée sous son espace de noms avec le package qui l’est fourni et un résumé d’une ligne de ce qu’elle fait, de sorte qu’un résultat est utilisable sans deuxième members appel :

[40] Microsoft.UI.Xaml.Media
    Class Microsoft.UI.Xaml.Media.AcrylicBrush  [Microsoft.WindowsAppSDK.WinUI 1.8.260224000]
        Paints an area with a semi-transparent material that uses multiple effects including blur and a noise texture.

Ajoutez --verbose également l’impression du fichier de cache sur disque qui sauvegarde chaque espace de noms, ce qui est utile lors du diagnostic d’un index obsolète ou inattendu.

L’exécution winapp find-api sans requête du tout imprime un bref résumé de l’utilisation et quitte 0 : il s’agit d’une demande d’aide, et non d’une recherche qui n’a rien trouvé.

Étendues. Chaque réponse provient exactement d’une étendue, signalée comme scope dans --json et sous forme de note dans la sortie de texte :

  • project - le projet dans le répertoire actif (ou --project / --project-dir). Couvre le SDK Windows, le SDK d'application Windows et les propres packages NuGet du projet. Les métadonnées SDK d'application Windows sont la version référencée par le projet : si l’ordinateur dispose d’un application Windows Runtime plus récent installé, find-api avertit et laisse-le hors service plutôt que de confirmer que les types sur utilisant le projet ne peuvent pas être compilés.
  • sdk- le kit SDK Windows à l’échelle de l’ordinateur + métadonnées SDK d'application Windows, utilisé automatiquement lorsque le répertoire actif ne contient aucun projet et aucune solution. Cela permet find-api d’explorer les API avant l’existence d’un projet et n’a pas besoin d’accès réseau. Il n’inclut délibérément pas de packages NuGet tiers. Par conséquent, un type de (par exemple) le Kit de ressources community n’est pas trouvé dans cette étendue.

Une requête à partir d’un répertoire sans projet et aucune solution n’est toujours répondue par l’étendue sdk ( jamais selon le projet qui se produit dans le cache partagé), de sorte que les résultats ne dépendent jamais d’un état global non lié. Passez --project sdk pour sélectionner explicitement l’étendue du Kit de développement logiciel (SDK) à partir d’un projet et winapp find-api refresh --project sdk pour la reconstruire après l’installation d’un nouveau sdk Windows.

Répertoires de solution. À partir d’un répertoire contenant un .sln/.slnx fichier projet sans fichier projet, les projets que la solution génère répondent au lieu de l’étendue : ils sont indexés à la sdk demande, de sorte que leurs packages NuGet sont inclus. Lorsque la solution génère plusieurs projets indexés, la requête les répertorie et les demande --project <name> plutôt que de les sélectionner.

Commandes:

  • (nu)find-api "<query>" ["<query>"...] - Rechercher des noms de membres et de type, revenir à leurs résumés documentés, regroupés par espace de noms
  • members <type> [<type>...] [--filter <text>] - Répertorier les propriétés, les événements et les méthodes d’un type (membres déclarés avec des signatures, membres hérités résumés en déclarant le type)
  • check-property <type> <property> [<property>...] - Vérifiez que les propriétés existent sur un type (quitte non zéro le cas échéant). Une propriété en lecture seule est signalée avec ⚠️ et « lecture seule, ne peut pas être affectée » au lieu d’une simple ✅, donc une propriété telle que n’est pas erronée pour quelque chose que ActualWidth vous pouvez définir. Les noms de propriété respectent la casse, car C# et XAML sont : check-property Button background quitte non zéro et offre Background comme une correspondance proche plutôt que de signaler un nom que vous ne pouvez pas écrire.
  • enums <type> [<type>...] [--filter <text>] - Répertorier les valeurs d’une énumération (quitte non zéro lorsque le type n’est pas une énumération)
  • packages - Répertorier les packages de métadonnées indexés, avec des nombres de types/membres par package
  • stats - Afficher les statistiques d’index d’agrégation (packages, espaces de noms, types, membres, .winmd fichiers)
  • refresh [--scan] - Régénérez l’index d’un projet (--scan indexe chaque projet sous le répertoire). Avec --project <name>, un nom qui correspond à aucun projet indexé unique échoue au lieu d’indexer le répertoire actif.

Batching.search, members, enumset check-property accepte plusieurs sujets dans un appel. Pour un agent IA, il s’agit du levier de coût unique le plus important : le coût marginal d’une recherche est dominé par le aller-retour (chaque appel envoie à nouveau la conversation), et non par la taille de la charge utile, donc un appel répondant à dix questions est beaucoup moins cher que dix appels.

  • Un seul objet retourne exactement la forme de charge utile qu’il a toujours, dans le texte et --json.
  • Deux sujets ou plus retournent une enveloppe , { "count": N, "results": [ ... ] } en --json, chaque élément étant la charge utile à objet unique normale ; check-property ajoute missingCount. La sortie de texte affiche chaque sujet dans une séquence sous un en-tête d’étendue.
  • check-property les propriétés par lots d’un type : le premier argument est le type, chaque argument après qu’il s’agit d’une propriété. En mode batch, une propriété qui existe imprime une seule ✅ ligne ; les détails quasi-manquants complets ne sont imprimés que pour ceux qui ne le font pas.
  • Un lot se ferme 0 uniquement si chaque sujet a été résolu et a été trouvé , donc un lot est toujours sûr pour la porte codegen sur.

Classement de la recherche. Une requête qui correspond exactement à un nom de type est classée avant les correspondances partielles et, lorsqu’un nom court est partagé par plusieurs espaces de noms, seuls les collisions de nom exact sont répertoriées comme ambiguës , une requête comme NavigationView celle qui signale la poignée d’espaces de noms qui définissent ce type exact plutôt que chaque espace de noms contenant un symbole nommé de même nom. La liste d’ambiguïtés --maxobéit, et les résultats normaux sont toujours imprimés sous celui-ci.

Types names.members, check-propertyand enums accept a short name (NavigationView) or a fully-qualified one (Microsoft.UI.Xaml.Controls.NavigationView). Lorsqu’un nom court est partagé par un type moderne et son jumeau UWP hérité Microsoft.*Windows.*, le Microsoft.* type répond , c’est-à-dire la projection qu’une application utilise SDK d'application Windows — et le nom complet résolu est toujours affiché. Toute autre collision quitte non zéro et répertorie les candidats au lieu de deviner.

Signatures de méthode. Une signature est imprimée de la façon dont vous écrivez l’appel : une méthode que vous appelez sur le type plutôt que sur une instance est affichée avec static, et un paramètre de référence est affiché avec le mot clé dont il a réellement besoin — out, inou ref. Boolean TryGetValue(String key, out String value)Lit doncTryGetValue, qui se compile comme écrit.

Options :

  • --max <n> - Nombre maximal de résultats de recherche groupés d’espaces de noms (valeur par défaut 5; recherche uniquement). Limite également la liste d’ambiguïtés. Par conséquent, une courte requête qui se heurte à de nombreux espaces de noms reste lisible.
  • --filter <text> - Limitez une liste et membersenums: correspondance de sous-chaîne ne respectant pas la casse sur le nom de membre/valeur. Mieux utilisé sur les types avec des centaines de membres. La plupart des énumérations sont suffisamment petites pour vider l’ensemble (même Symbol, le plus grand dans WinUI à 197 valeurs), de sorte que le filtrage des coûts coûte généralement plus qu’il économise une fois que vous facteurz dans une seconde estimation. Ne réexécutez jamais la même commande avec un texte de filtre différent : videz-la une fois et lisez-la.
  • --all - Sur members, répertoriez l’aire complète : signatures complètes pour les membres hérités, ainsi que les statiques d’identificateur de propriété de dépendance et les descriptions par membre, dont toutes les descriptions non filtrées (voir Taille de liste ci-dessous). --verbose l’implique ; utilisez --all quand vous souhaitez --jsonégalement , qui ne peut pas être combiné avec --verbose.
  • --scan - Détecter et indexer de manière récursive chaque projet sous le répertoire (refresh uniquement)
  • --project <name>- Project à interroger (correspond au .csproj/.vcxproj nom) ou sdk à interroger l’étendue du Kit de développement logiciel Windows (SDK) à l’échelle de l’ordinateur
  • --project-dir <path>- Project répertoire à interroger (valeur par défaut du répertoire actif). Un chemin d’accès qui n’existe pas est une erreur : il n’est jamais répondu en mode silencieux à partir de l’étendue sdk .
  • --json - Émettre une charge utile lisible par l’ordinateur sur stdout (prise en charge par chaque verbe). Les charges utiles de requête identifient l’index qui a répondu via scope (project ou sdk) projectNameet projectDir (absent de l’étendue du KIT DE DÉVELOPPEMENT LOGICIEL) : les noms de projet ne sont pas uniques entre les répertoires, c’est-à-dire projectDir l’identité fiable. Sous --jsonchaque échec , y compris les erreurs d’argument/d’analyseur, telles qu’un non-entier --max , est émise en tant qu’objet plat {"error": "..."} sur stdout avec un code de sortie non nul, de sorte que la sortie reste lisible par l’ordinateur.

Exemples :

# Search
winapp find-api "acrylic brush"
winapp find-api NavigationView --max 10

# Inspect and validate
winapp find-api members Microsoft.UI.Xaml.Controls.NavigationView
winapp find-api check-property Button Background
winapp find-api enums Symbol

# Batch — one call instead of one per subject
winapp find-api check-property InfoBar Severity IsOpen Message Title
winapp find-api members InfoBar TeachingTip ContentDialog
winapp find-api enums InfoBarSeverity Visibility
winapp find-api "acrylic brush" "teaching tip" --max 5

# Narrow a large type instead of dumping it and grepping
winapp find-api members Button --filter background

# Full member surface: inherited signatures, dependency-property statics, descriptions
winapp find-api members Button --all

# Manage the index
winapp find-api refresh

# Explore the Windows SDK with no project at all (e.g. before scaffolding an app)
winapp find-api "acrylic brush"          # from an empty directory -> scope: sdk
winapp find-api members Button --project sdk

Lorsqu’elle --filter est appliquée, la sortie signale toujours le total non filtré (totalValuesou totalProperties/totalMethods/totalEventsen --json), afin qu’une vue étroite ne soit jamais erronée pour une petite API. Un filtre qui ne correspond toujours à rien ne se ferme 0 et dit si explicitement : « rien ne correspond à votre filtre », et non « aucun type de ce type ».

Taille de la liste. Une liste non filtrée est la forme coûteuse : members Button couvre 288 membres dont 280 sont hérités members de 6 types de base. Un appel non filtré est une requête d’orientation (« qu’est-ce que ce type, à peu près ce qu’il peut faire ? »), de sorte qu’il répond et omet les parties dont rien n’est écrit :

  • Signatures membres héritées : les membres hérités sont regroupés en déclarant le type et répertoriés par nom uniquement, de sorte que la forme de la surface héritée est toujours visible sans 280 signatures complètes.
  • Statiques de l’identificateur de propriété de dépendance (BackgroundProperty) : 28% des propriétés d’un contrôle WinUI standard. Ils existent pour être passés à GetValue/SetValue, non attribués.
  • Descriptions par membre : la prose xml-doc, environ 16% de la charge utile.
  • Champs implicites par leur environnement dans --json: kind (implicite par le tableau contenantproperties//eventsmethods), returnType (jeton de début de signature), et inherited quand false (implicite par ).declaringType

Ce qui a été omis est toujours signalé (hiddenDependencyProperties, descriptionsOmittedet un hint in --json; une ligne « omis : » dans le texte), et les totaux décrivent toujours le type entier. Les deux --filter et --all voient l’aire complète avec des signatures et descriptions complètes, donc members Button --filter BackgroundProperty trouve toujours l’identificateur et members Button --filter Click retourne Clicktoujours la signature héritée. Mesuré sur samples/winui-app, cela prend members Button --json de 91 954 à 10 567 caractères (−88,5%) tout en laissant et --all en octets --filter identiques.

Correspondance d’une requête. winapp find-api "language model" se classe LanguageModel au-dessus des correspondances dont les mots sont répartis entre les espaces de noms et les membres, y compris en dehors d’un projet lorsque le type est indexé. La recherche est lexicale, pas sémantique : elle correspond à des mots d’identificateur entiers plutôt qu’à une série de lettres, donc llm trouve IImageLLMAdapterSession , mais pas ScrollMode. Lorsqu’une requête ne correspond à aucun nom, elle est tentée par rapport aux résumés documentés des types et des membres, c’est-à-dire ce qui permet "random-access stream" de trouver IRandomAccessStream. Les descriptions se classent sous chaque correspondance de nom et seuls les résumés des packages réellement fournis sont pouvant faire l’objet d’une recherche. Un package sans documentation XML ne contribue à aucun texte de description.

Projets sans fichier projet MSBuild. Une application Electron (ou toute autre application non .NET pilotée par winapp.yaml) n’a donc pas et donc pas project.assets.json.csproj . find-api indexe celle-ci à partir de l’écriture .winapp/winmds.lock.jsonwinapp restore , qui enregistre la même chose : chaque package résolu, sa version et les .winmd fichiers qu’il contribue. Un tel projet est nommé après son répertoire et son index est obsolète lorsque le fichier de verrouillage est réécrit. Répertoire qui contient à la fois un .csproj répertoire et un winapp.yaml indexé à partir du .csproj, qui est la description plus précise de ce que le projet compile.

Les réponses négatives sont qualifiées lorsque l’index est incomplet. Si les métadonnées d’un package n’ont pas pu être lues, « aucun type de ce type » et « ce package n’a jamais été indexé » sont identiques et agissent sur le premier lorsqu’il s’agit vraiment du deuxième génère du code sur une API que vous avez dit n’existe pas. Ainsi, chaque réponse négative, y compris un search qui retourne zéro résultat, porte une note indiquant que l’index est partiel et pointe vers winapp find-api refresh. Les réponses positives ne sont pas affectées.

Noms de types génériques. Les métadonnées stockent des types génériques avec un suffixe arity (IAsyncOperation`1), ce qui n’est pas la façon dont personne les écrit. members, enumset check-property acceptez chaque formulaire : IAsyncOperation, IAsyncOperation<StorageFile>et IAsyncOperation`1 tous se résolvent au même type. Un nom nu correspond à n’importe quelle arité ; une arité indiquée (dans l’une ou l’autre notation) doit correspondre. Holder<A, B> Elle ne sera donc pas résolue en un seul paramètre Holder<T>.

--json les charges utiles omettent les diagnostics. Les chemins de fichier de cache apparaissent uniquement sous --verbose (sortie de texte correspondante, où ils étaient déjà détaillés uniquement) et les tableaux de suggestions vides sont omis plutôt que sérialisés en tant que [].

Codes de sortie :search sans accès, check-property sur une propriété manquante, et enums sur un type non-enum tous les types de sortie non nuls : la génération de code de porte et les vérifications CI sur eux. Un appel par lots quitte non zéro si un objet échoue. Une propriété en lecture seule n’est pas un échec : elle existe, donc check-property quitte 0 et signale-la dans la sortie (writable: false in --json). Une init propriété signale writable: false pour la même raison : elle peut être définie dans un initialiseur d’objet, et sa signature indique { get; init; }, mais l’affectation ultérieurement ne se compile pas.

Connexe :find-api répond « cette API existe-t-elle et quels sont ses membres ? » ; permet find-ui de rechercher un exemple WinUI fonctionnel pour un contrôle.


générer des liaisons de nœud

(Disponible dans le package NPM uniquement) Générez des liaisons JS pour les API SDK d'application Windows. Les liaisons sont déclarées par un "winapp": { "jsBindings": {...} } espace de noms dans package.json et écrites dans .winapp/bindings/.

npx winapp node generate-bindings [options]

Options :

  • --verbose, -v - Activer la sortie de codegen détaillée par fichier
  • --quiet, -q - Supprimer la progression et la sortie d’information

Résultat :

  • Lit le bloc et winapp.jsBindings l’écrit package.json par le dernier winmds.lock.json, puis émet des liaisons typéeswinapp restore.js + dans .d.ts.winapp/bindings/
  • Ne modifiepackage.json pas : il s’agit d’un régénérateur passif. L’ajout du bloc et de la winapp.jsBindings dépendance d’exécution se produit lors @microsoft/dynwinrt de l’activation winapp init des liaisons JS ; cette commande échoue rapidement si le bloc est absent
  • Avertit (mais n’écrit pas) s’il @microsoft/dynwinrt manque vos dépendances , exécuté npm install après init l’avoir ajouté

Note

Les liaisons sont npm uniquement : elles nécessitent un appel via npx winapp (le @microsoft/winappcli package npm) ; l’interface CLI de winget autonome ne les surface pas. Exécutez de manière interactive et optez winapp init , ou utilisez winapp init . --use-defaults --add-js-bindings, avant d’utiliser cette commande pour régénérer les liaisons. Si vous modifiezwinapp.yaml, exécutez npx winapp restore pour actualiser Windows dépendances avant de régénérer.

Exemples :

# Regenerate JS bindings in the current project
npx winapp node generate-bindings

# Regenerate after editing winapp.jsBindings, with verbose output
npx winapp node generate-bindings --verbose

Consultez le guide des liaisons JS pour le workflow de bout en bout et les options de winapp.jsBindings configuration.


node create-addon

(Disponible uniquement dans le package NPM) Générer des modèles de complément C++ ou C# natifs avec Windows SDK et l’intégration SDK d'application Windows.

npx winapp node create-addon [options]

Options :

  • --name <name> - Nom du module complémentaire (valeur par défaut : « nativeWindowsAddon »)
  • --template - Sélectionnez le type de module complémentaire. Les options sont cs ou cpp (par défaut : cpp)
  • --verbose - Activer la sortie détaillée

Résultat :

  • Crée un répertoire d'extension avec des fichiers de modèle
  • Génère binding.gyp et addon.cc avec des exemples de sdk Windows
  • Installe les dépendances npm requises (nan, node-addon-api, node-gyp)
  • Ajoute un script de génération à package.json

Exemples :

# Generate addon with default name
npx winapp node create-addon

# Generate custom named addon
npx winapp node create-addon --name myWindowsAddon

node add-electron-debug-identity

(Disponible dans le package NPM uniquement) Ajoutez l’identité d’application au processus de développement Electron à l’aide d’un empaquetage partiellement alloué. Nécessite un Package.appxmanifest (créez-en un avec winapp init ou winapp manifest generate si vous n’en avez pas).

Important

Il existe un problème connu lié à l’empaquetage d’applications Electron éparses qui provoquent le blocage de l’application au démarrage ou non au rendu du contenu web. Le problème a été résolu dans Windows, mais il n’a pas encore été propagé aux appareils Windows externes. Si vous voyez ce problème après l’appel add-electron-debug-identity, vous pouvez désactiver le bac à sable dans votre application Electron à des fins de débogage avec l’indicateur --no-sandbox . Ce problème n’affecte pas l’empaquetage MSIX complet.

Pour supprimer l'identité de débogage d'Electron, utilisez winapp node clear-electron-debug-identity.

npx winapp node add-electron-debug-identity [options]

Options :

Choix Description
--manifest <path> Chemin d’accès à Package.appxmanifest personnalisé (par défaut : Package.appxmanifest dans le répertoire actif)
--no-install N'installez pas ou ne modifiez pas les dépendances ; ne configurez que l'identité de débogage d'Electron
--keep-identity Conservez l’identité du manifeste as-is, sans ajouter .debug le nom du package et l’ID d’application
--verbose Activer la sortie détaillée

Résultat :

  • Inscrit l’identité de débogage pour electron.exe processus
  • Permet de tester les API nécessitant des identités dans le développement Electron
  • Utilise package.appxmanifest existant pour la configuration des identités

Exemples :

# Add identity to Electron development process
npx winapp node add-electron-debug-identity

# Use a custom manifest file
npx winapp node add-electron-debug-identity --manifest ./custom/Package.appxmanifest

node effacer-Électron-débogage-identité

(Disponible dans le package NPM uniquement) Supprimez l’identité du package du processus de débogage Electron en restaurant le electron.exe d’origine de la sauvegarde.

npx winapp node clear-electron-debug-identity [options]

Options :

Choix Description
--verbose Activer la sortie détaillée

Résultat :

  • Restaure electron.exe à partir de la sauvegarde créée par add-electron-debug-identity
  • Supprime les fichiers de sauvegarde après la restauration
  • Retourne Electron à son état d’origine sans identité de package

Exemples :

# Remove identity from Electron development process
npx winapp node clear-electron-debug-identity

Options globales

Toutes les commandes prennent en charge ces options globales :

  • --verbose, -v - Activer la sortie détaillée pour la journalisation détaillée
  • --quiet, - -q Supprimer les messages de progression
  • --help, -h - Afficher l’aide de la commande

Répertoire global du cache

Winapp crée un répertoire pour mettre en cache des fichiers qui peuvent être partagés entre plusieurs projets.

Par défaut, winapp crée un répertoire dans $UserProfile/.winapp le répertoire global du cache.

Pour utiliser un autre emplacement, définissez la variable d’environnement WINAPP_CLI_CACHE_DIRECTORY .

En cmd :

REM Set a custom location for winapp's global cache
set WINAPP_CLI_CACHE_DIRECTORY=d:\temp\.winapp

Dans PowerShell et pwsh :

# Set a custom location for winapp's global cache
$env:WINAPP_CLI_CACHE_DIRECTORY=d:\temp\.winapp

Winapp crée ce répertoire lorsqu’une commande en a d’abord besoin.

Quand winapp ne peut pas écrire dans le répertoire global du cache

Certains environnements, tels que les bacs à sable d’agent qui autorisent uniquement les écritures dans le projet actuel, bloquent l’accès à %USERPROFILE%\.winapp. La plupart des commandes fonctionnent toujours là, et la vérification de la mise à jour est ignorée. Si winapp n’a pas terminé sa première exécution dans ce répertoire, chaque exécution imprime également une notification de télémétrie d’une ligne à stderr.

Ces commandes doivent écrire dans le répertoire du cache et s’arrêter avec une erreur qui nomme le chemin d’accès :

Commande Ce qu’il écrit
find-api Index d’API, quand il doit être généré ou actualisé. Un index de date up-toexistant est toujours lu.
store L'interface CLI Microsoft Store Développeur, la première fois qu'elle est installée.

Pour résoudre ce problème, définissez WINAPP_CLI_CACHE_DIRECTORY sur un dossier winapp peut écrire (par exemple, un à l’intérieur de votre projet), puis réessayez.

winapp ui les commandes conservent leur état de prise de tour en %USERPROFILE%\.winapp\state\ui. S’ils ne peuvent pas y accéder, ils s’exécutent toujours, mais sans attendre d’autres winapp ui commandes sur le même bureau, et impriment un avertissement (omis avec --json ou --quiet). Évitez d’exécuter d’autres winapp ui commandes sur ce bureau en même temps.

Windows commandes sandbox conservent leur état.%USERPROFILE%\.winapp\state Si ce dossier n’est pas accessible en écriture, il s’arrête et sandbox_state_unavailable nomme la variable à définir.

Vérifications de mise à jour

L’interface CLI winapp vérifie régulièrement les nouvelles versions et affiche une notification d’une ligne quand une mise à jour est disponible. Cette vérification s’exécute en arrière-plan et n’ajoute aucune latence aux commandes.

Les vérifications de mise à jour sont automatiquement désactivées dans les environnements CI (GitHub Actions, Azure Pipelines, etc.).

Pour désactiver manuellement les vérifications de mise à jour, définissez la variable d’environnement WINAPP_CLI_UPDATE_CHECK sur 0.

En cmd :

set WINAPP_CLI_UPDATE_CHECK=0

Dans PowerShell et pwsh :

$env:WINAPP_CLI_UPDATE_CHECK = "0"

Pour rendre cette opération permanente :

[System.Environment]::SetEnvironmentVariable('WINAPP_CLI_UPDATE_CHECK', '0', 'User')

Identité du flux de travail de l’interface utilisateur

winapp ui les commandes qui pilotent le bureau physique prennent toujours des tournures coopératives, de sorte que deux flux de travail s’exécutant à la fois ne peuvent pas voler le focus de l’autre ou ignorer les menus de l’autre. Cet arbitrage n’a besoin d’aucune installation et ne peut pas être désactivé.

Ce qui est facultatif est la continuité. Par défaut, chaque commande est une capture autonome qui libère le bureau dès qu’elle se termine. Pour conserver le bureau sur plusieurs commandes, donnez-leur le même ID de flux de travail :

$env:WINAPP_UI_WORKFLOW_ID = [guid]::NewGuid().ToString()

Utilisez la même valeur pour coopérer les processus (par exemple, un enregistrement et les clics qu’il doit capturer) et différentes valeurs pour les flux de travail indépendants. Chaque commande sans ID est son propre flux de travail one-shot, même quand plusieurs sont lancés à partir d’un interpréteur de commandes, de sorte que les hôtes qui démarrent un interpréteur de commandes frais doivent injecter la même valeur explicite dans chacun d’eux. La valeur est opaque, n’est jamais traitée en tant qu’informations d’identification et n’est jamais conservée en tant que hachage SHA-256. Consultez UI Automation → Coordination des flux de travail simultanés de l’interface utilisateur.

ui

Inspectez et interagissez avec les interfaces utilisateur d’application Windows en cours d’exécution à l’aide de UI Automation (UIA). Exécuter winapp ui --help pour le flux de travail principal ; consultez l’automatisation de l’interface utilisateur pour le guide complet.

winapp ui [command] [options]

Commandes:

  • status - Se connecter à l’application et afficher les informations
  • inspect - Arborescence des éléments View
  • search - Rechercher des éléments par sélecteur
  • get-property - Lire les propriétés de l’élément
  • get-text / get-value - Lire la valeur/le texte à partir de l’élément (TextPattern, ValuePattern ou Name)
  • screenshot - Capturer la fenêtre/l’élément en tant que PNG (plusieurs fenêtres forment une png composite étiquetée ; voir l’étendue de capture)
  • record- Enregistrer une zone de fenêtre/élément dans une vidéo H.264 MP4 (Windows Graphics Capture + Media Foundation)
  • invoke - Activer l’élément (cliquez, basculez, développez) ; --action sélectionne une opération exacte (voir invoke)
  • click - Cliquer sur un élément via la simulation de souris (pour les contrôles qui ne prennent pas en charge l’appel)
  • hover - Déplacer la souris vers l’élément pour déclencher des info-bulles, des menu volants et des états de pointage (par défaut : 800 ms)
  • drag - Faites glisser la souris d’un point vers un autre, par sélecteur d’élément ou coordonnées d’écran x,y (réorganiser, redimensionner, curseurs, glisser-déplacer)
  • touch- Injecter des mouvements tactiles synthétiques (appuyez deux fois, appuyez longuement, balayez, pincez, étirez) au centre d’un élément ou à des coordonnées d’écran x,y
  • pen - Injecter une entrée de stylet/stylet synthétique — appuis et traits d’encre avec pression, inclinaison et gomme configurables
  • send-keys - Envoyer une entrée de clavier synthétique (touches nommées, combos, raw vk=0xNN ou texte littéral) à une fenêtre
  • set-value - Définir la valeur sur l’élément modifiable (texte, nombre) ; revient à LegacyIAccessible put_accValue pour les contrôles TextPattern-only rich-edit
  • focus - Déplacer le focus clavier
  • scroll-into-view - Élément Scroll visible
  • wait-for - Attendre l’état de l’élément
  • list-windows - Répertorier toutes les fenêtres d’une application
  • get-focused - Signaler l’élément actuellement axé
  • yield - Relâchez le tour d’interface utilisateur du flux de travail actuel ; nécessite WINAPP_UI_WORKFLOW_ID

Options :

  • -a, --app <app> - Application cible (nom, titre ou PID)
  • -w, --window <hwnd> - Fenêtre cible par HWND (stable)
  • --on <target> - Exécutez n’importe quel ui verbe dans sandbox; noms, PID et poignées de fenêtre font référence à l’invité. Les sorties sont remises à l’hôte. Consultez l’automatisation de l’interface utilisateur de bac à sable pour la configuration, la coordination des flux de travail et les exigences du client.
  • --type, , - --root--class-name Affiner un sélecteur sur les commandes répertoriées dans les requêtes délimitées et typées

enregistrement d’interface utilisateur

Enregistrez une fenêtre ou une région d’élément dans un FICHIER MP4 H.264.

# Record a window for 10 seconds at 15 fps
winapp ui record -a Calculator --duration-sec 10 --fps 15 -o demo.mp4

# Record until Ctrl+C, downscaled so the longest edge is 1280px
winapp ui record -a "My App" --duration-sec 0 --max-edge 1280 -o capture.mp4

# Record just one element's region
winapp ui record -a "My App" btn-save-1234 -o button.mp4

# Keep an agent-readable timeline alongside the MP4
winapp ui record -a Calculator --frames --duration-sec 10 --fps 10 -o evidence.mp4

Options d’enregistrement :

  • --duration-sec <n> - Durée d’enregistrement en secondes. 0 enregistre jusqu’à Ctrl+C (valeur par défaut 0).
  • --fps <n> - Images par seconde à capturer (par défaut 15).
  • --max-edge <px> - Mise à l’échelle descendante pour que le bord le plus long soit au maximum de ce nombre de pixels (0 = pas de mise à l’échelle descendante).
  • --capture-screen - Capture à partir de l’écran de sorte que les superpositions/fenêtres contextuelles sont incluses (peut capturer les fenêtres d’occluding).
  • -o, --output <path> - Chemin de sortie .mp4 (valeur par défaut recording-<timestamp>-<guid>.mp4).
  • --overwrite - Remplacer les sorties d’enregistrement existantes une fois la nouvelle prise terminée ; Les sorties existantes sont rejetées par défaut. Les bundles d’images précédents sont conservés. Consultez la récupération de sortie de l’enregistrement.
  • --frames - Écrire des JPEG horodatés, frames.ndjsonet manifest.json à <output-name>.frames. Prend en charge 1-30 fps et --max-edge 64-4096 (par défaut 1280), avec une limite de données frame-1 Gio.

Avec --json, le résultat final inclut le chemin de sortie, les dimensions, le codec, le mode de capture, la cadence, la raison d’arrêt, facultatif frameArtifactset les avertissements.

Pour obtenir une documentation complète, consultez docs/ui-automation.md.