Exécution de Windows Sandbox

Créez sur votre machine, puis exécutez et automatisez l’application dans Windows Sandbox :

winapp run . --on sandbox --detach
winapp ui inspect --on sandbox -a MyApp
winapp ui invoke --on sandbox SubmitButton -a MyApp

Remplacez MyApp par le nom de votre application ou le PID invité imprimé par run. --detach retourne après le lancement afin que la commande suivante puisse inspecter l’application ; sans cela, run attend que l’application se termine. Le sandbox reste actif entre les commandes et les recompilations.

Avant de commencer

  • Utilisez Windows 11 24H2 ou version ultérieure sur une édition prise en charge, avec la virtualisation matérielle activée.
  • L’application winapp invitée prend en charge x64 et Arm64. Une application x86 nécessite la prise en charge du système invité pour pouvoir s’exécuter, ainsi que des dépendances x86 correspondantes ; un environnement d’exécution x64 ne suffit pas pour une application x86.
  • Conservez la session hôte déverrouillée pour l’entrée réelle et la capture d’écran.

Activez Windows bac à sable pour activer ou désactiver les fonctionnalités de Windows, ou exécutez-la à partir d’un terminal administrateur :

dism.exe /Online /Enable-Feature /FeatureName:Containers-DisposableClientVM /All /NoRestart

Enregistrez votre travail et redémarrez Windows lorsque vous êtes prêt. Ouvrez ensuite Windows bac à sable à partir du menu Démarrer et terminez toute installation ou mise à jour du client. winapp n’active ni la fonctionnalité, ni n’installe le client, ni ne demande une élévation de privilèges, ni ne redémarre Windows. Si les prérequis sont manquants, il s’arrête avec les instructions d’installation ; un redémarrage Windows en attente observé est signalé séparément.

Une connexion à froid ou une reconnexion peut brièvement prendre le focus. Une fois connecté, winapp place la fenêtre Sandbox derrière la fenêtre que vous utilisiez, sans l’activer ; basculez vers Windows Sandbox dans la barre des tâches pour voir le système invité. Contrairement à un Sandbox ouvert à partir de l’écran de démarrage, la fermeture de cette fenêtre ne met pas fin au Sandbox ; il continue à fonctionner. Pour le voir à nouveau, exécutez wsb list, puis wsb connect --id <id>. Pour y mettre fin, consultez La suppression d’une application et la fin du Sandbox.

Important

Les builds s’exécutent toujours sur votre ordinateur. L’évaluation du projet, la restauration et la compilation ne sont pas isolées. --on sandbox ne rend pas sans danger la génération d’un projet non fiable.

Un bac à sable est un environnement partagé. Les applications et les flux de travail à l’intérieur de celui-ci partagent l’utilisateur, le bureau, le Registre, les packages, les runtimes et l’accès réseau. Ils peuvent observer ou interférer les uns avec les autres. Utilisez des machines distinctes pour les flux de travail qui ne se font pas mutuellement confiance.

Windows autorise un bac à sable à la fois. winapp réutilise une instance en cours d’exécution, y compris celle que vous avez ouverte vous-même. Cette préparation ajoute les dossiers d’amorçage partagés de winapp, l’agent invité, le mode Développeur et une règle de pare-feu entrante. winapp n’arrête pas une instance adoptée ni supprime les applications non liées. Il n’y a aucun basculement silencieux vers l’hôte : une commande qui demande Sandbox s’y exécute ou échoue.

Exécution et régénération

winapp run .\MyApp.csproj --on sandbox --detach --json
winapp run .\publish --on sandbox --detach
winapp run . --on sandbox --clean --detach

Les options de génération, telles que --configuration, --arch, --framework, --property, --no-build et --no-restore, s’appliquent sur l’hôte. L’inscription, le lancement et le débogage se produisent dans l’invité ; l’application n’est pas inscrite sur votre ordinateur.

Option Effet dans le bac à sable
--detach Retourner après le lancement au lieu d’attendre la sortie
--no-launch Déployer et enregistrer sans lancer
--clean Réinstallez ce déploiement et effacez ses données d’application
--unregister-on-exit Supprimer cette inscription de package après la fermeture de l’application
--with-alias Lancer son alias d’exécution invité avec des flux transférés
--debug-output Diffuser en continu la sortie du débogage invité ; applications empaquetées uniquement

Les applications non empaquetées lancent leur exécutable à partir du dossier déployé. Ils n’ont aucun package à enregistrer. --debug-output est refusé pour les exécutions Sandbox non empaquetées.

La réexécution transfère les fichiers modifiés et supprime les fichiers supprimés de la sortie de build. Les données d’application sont conservées, sauf si vous demandez --clean. Un déploiement incomplet ne démarre pas ; réessayer régénère sa copie invitée. Si les fichiers de construction changent pendant que winapp les prépare, terminez la compilation et réessayez.

Les commandes d’interface utilisateur chaudes signalent uniquement leur résultat, sans répéter un message de préparation de bac à sable. Le démarrage du bac à sable et le rétablissement de la connexion indiquent toujours la progression. Utiliser --verbose pour les délais de connexion et les détails de diagnostic ; --quiet et --json désactivent l’affichage de la progression. Les exécutions JSON incluent un ID de processus invité et une étendue cible :

{
  "ProcessId": 4212,
  "Sandbox": true,
  "ProcessScope": "sandbox",
  "UiTargetArgs": "--on sandbox -a 4212",
  "ExecutionTarget": {
    "Kind": "sandbox",
    "Id": "default",
    "Architecture": "arm64",
    "Epoch": "..."
  }
}

Il s’agit de champs supplémentaires dans le résultat de l’exécution, et non d’un document distinct. Copiez la valeur entière UiTargetArgs lors de l’inspection de l’application : winapp ui inspect --on sandbox -a 4212. Retrouvez les PID et les poignées de fenêtre après avoir recréé le Sandbox ; ils appartiennent à cette génération de Sandbox, et non à l’hôte ou à un futur invité.

Applications détachées et durée de vie de l’agent

Une application détachée non empaquetée se termine si l’agent invité s’arrête, y compris pendant la réparation de l’agent. S’il disparaît entre les commandes, réexécutez --detach et redécouvrez sa cible d’interface utilisateur. Attendre l’application plutôt que la détacher vous permet d’observer sa sortie ; elle ne fait pas survivre l’application à la perte de l’agent. Les applications empaquetées utilisent l’activation de Windows et non la durée d’exécution du processus de l’agent. La fermeture ou le redémarrage du bac à sable termine toutes les applications à l’intérieur.

Environnements d’exécution partagés

winapp vérifie les dépendances du package de l’application, les exigences du SDK d’application Windows et *.runtimeconfig.json avant son lancement. Il utilise les caches de l’hôte ou télécharge les composants nécessaires, puis installe les environnements d’exécution pris en charge manquants dans l’invité, et non sur votre ordinateur.

La configuration requise pour les packages inclut l’éditeur, la version et l’architecture. La sélection du runtime .NET partagé respecte la stratégie de report et l’architecture configurées pour l’application ; ne partez pas du principe qu’un runtime plus récent de la même version majeure fonctionnera.

Si une infrastructure, une configuration d’exécution ou une dépendance ne peut pas être prise en charge, la commande échoue explicitement avant le lancement et identifie l’exigence. Suivez l’action associée à cette erreur. Lorsqu’il est pris en charge par votre projet, la publication autonome supprime la nécessité du runtime partagé correspondant ; elle ne supprime pas les dépendances de package non liées.

Automatisation de l’interface utilisateur

winapp ui list-windows --on sandbox
winapp ui inspect --on sandbox -a MyApp
winapp ui invoke --on sandbox SubmitButton -a MyApp
winapp ui screenshot --on sandbox -a MyApp -o .\result.png

Chaque ui verbe accepte --on sandbox. Les noms d’application, les PID, les identifiants de fenêtre et les sélecteurs sont résolus dans le système invité. Utiliser -a/--app ou -w/--window pour les commandes ciblées sur l’application ; winapp ne suppose pas la dernière application lancée. Si vous omettez --on sandbox, votre bureau hôte est sélectionné à la place.

Les entrées réelles et l’enregistrement nécessitent un client Sandbox connecté et non réduit. L’inspection en lecture seule reste possible lorsque la saisie ne l’est pas. winapp restaure une fenêtre Sandbox réduite derrière votre fenêtre active, sans l’activer. Si l’entrée n’est pas disponible après la reconnexion, la commande échoue au lieu de prétendre l’avoir fournie. Utilisez la commande reconnect dans l’erreur et réessayez.

Utilisez winapp target snapshot sandbox --json pour vérifier l’état de préparation du bureau sans démarrer ni vous reconnecter au bac à sable. Les fenêtres d’erreur du terminal reconnues ne sont pas comptabilisées comme des bureaux à distance. Si winapp ne peut pas vérifier le bureau sélectionné parce qu’il est toujours en cours de connexion ou ne peut pas être inspecté, l’état de préparation reste indisponible ; attendez, puis réessayez. Plusieurs bureaux distants peuvent toujours être ambigus. La capture instantanée ne ferme pas les fenêtres ni ne corrige leurs erreurs à votre place.

Consultez UI Automation pour les sélecteurs, les méthodes d’entrée et les assertions.

Coordination des flux de travail d’interface utilisateur dans le bac à sable

Utilisez une valeur WINAPP_UI_WORKFLOW_ID pour des commandes qui coopèrent, et une valeur différente pour chaque flux de travail indépendant. Définissez-le à chaque invocation, en particulier lorsque votre agent démarre un nouvel interpréteur de commandes pour chaque invocation d’outil. winapp transfère une identité hachée propre à la génération du Sandbox ; la valeur brute de l’hôte n’est pas envoyée à l’invité.

Par exemple, enregistrez et interagissez dans deux terminaux à l’aide de la même valeur. Choisissez une nouvelle valeur pour chaque nouveau flux de travail.

Terminal 1 :

$env:WINAPP_UI_WORKFLOW_ID = 'myapp-checkout-01'
winapp ui record --on sandbox -a MyApp --duration-sec 20 --frames -o .\checkout.mp4

Terminal 2, pendant l’exécution de l’enregistrement :

$env:WINAPP_UI_WORKFLOW_ID = 'myapp-checkout-01'
winapp ui invoke --on sandbox SubmitButton -a MyApp
$env:WINAPP_UI_WORKFLOW_ID = 'myapp-checkout-01'
winapp ui inspect --on sandbox -a MyApp

Une fois tous deux l’enregistrement et les actions terminés :

$env:WINAPP_UI_WORKFLOW_ID = 'myapp-checkout-01'
winapp ui yield --on sandbox

Un workflow nommé conserve son tour d’interface utilisateur pendant quatre secondes après sa dernière commande ; yield le libère immédiatement. Sans identifiant, chaque commande cède son tour une fois terminée. Un enregistrement sans ID bloque donc les autres processus de changement de bureau pendant toute sa durée. L’inspection en lecture seule n’attend pas. Les tours de l’interface utilisateur hôte et invité sont séparés.

Après une pause, inspectez à nouveau et rouvrez tout menu ou boîte de dialogue dont vous avez besoin : un autre workflow peut avoir utilisé le bureau invité. Les tournures coopératives n’isolent pas les applications les unes des autres.

Captures d’écran et enregistrements

Utilisez la capture ui pour la fenêtre d’une application, ou la capture target pour le bureau natif complet de l’invité, y compris le shell et les boîtes de dialogue du programme d’installation :

winapp ui record --on sandbox -a MyApp --duration-sec 10 --frames -o .\app.mp4
winapp target screenshot sandbox -o .\sandbox.png
winapp target record sandbox --duration-sec 20 --frames -o .\sandbox.mp4

Les sorties sont dirigées vers l’hôte, y compris lorsque vous omettez -o. Captures d’écran screenshot.pngpar défaut ; les enregistrements utilisent recording-<timestamp>-<guid>.mp4. Pour les enregistrements, --frames fournit également le <output-name>.frames répertoire contenant des JPEG, frames.ndjsonet manifest.json. Chemins d’accès de l’hôte du rapport de résultats. Les enregistrements cibles s’exécutent dans l’invité ; leurs fichiers hôtes deviennent disponibles une fois l’enregistrement terminé et la remise terminée.

target screenshot attend le tour de l’interface utilisateur de l’invité sans activer de fenêtre. Elle exclut la barre de titre et les bordures de la fenêtre Sandbox hôte. Son image PNG n’est pas mise à l’échelle : avec l’origine (0,0) de l’écran invité, les coordonnées de l’image sont directement utilisables par des commandes de saisie de coordonnées telles que ui drag ou ui touch --at, avec --on sandbox. Ajoutez l’origine signalée pour un bureau avec une origine négative. Utilisez --json pour lire coordinates.sourceBounds et coordinates.contentRect ; tous deux utilisent des pixels physiques et des bords droits/inférieurs exclusifs.

Les enregistrements cibles signalent les mêmes champs dans JSON et le manifeste de trame. Les images MP4 et JPEG partagent le mappage, notamment la mise à l’échelle --max-edge et le remplissage de l’encodeur. Pour mapper le pixel (x,y)de l’image, commencez par rejeter les points en dehors contentRect, puis calculez chaque coordonnée source en tant que sourceStart + floor((pixel - contentStart + 0.5) * sourceSize / contentSize). La mise à l’échelle descendante perd la précision ; utilisez un PNG natif quand des coordonnées exactes importent. Une modification des limites du bureau invité arrête l’enregistrement, display_changeden conservant uniquement les images avant la modification et en marquant le manifeste d’image partiel.

Un fichier MP4 existant ou le répertoire .frames associé est rejeté par défaut. Utilisez un nouveau chemin, ou passez --overwrite pour les remplacer une fois la nouvelle prise terminée. Les bundles d’images précédents sont conservés en tant que <output-name>.frames.previous-<id>, y compris lorsque le remplacement omet --frames. Une capture ayant échoué laisse l’ancien enregistrement intact.

Préférez une valeur positive --duration-sec pour les scripts et les agents. Les utilitaires npm uiRecord et targetRecord nécessitent durationSec ; leur signal d’annulation interrompt de force, et non via un arrêt propre. Consultez ui record pour connaître les valeurs prises en charge. Sans durée CLI, l’enregistrement attend un signal d’arrêt.

Ctrl+C après le démarrage de la capture peut finaliser et renvoyer un enregistrement avec succès.stopReason: cancelled D’autres interruptions peuvent conserver des images ou des vidéos utiles. Lisez stopReason, partialOutputet recoveryHint lorsque vous êtes présent et utilisez les chemins de preuve signalés plutôt que d’assumer une fin normale. Si la capture de l’ensemble du bureau devient indisponible pendant un enregistrement, elle s’arrête avec capture_unavailable au lieu de continuer à capturer un bureau qui n’est plus disponible. Il n’amène pas le bac à sable au premier plan pour sauver un cadre. La capture peut échouer avant la disponibilité d’une preuve utilisable.

Pour un enregistrement invité ayant échoué, la preuve récupérée est placée dans un répertoire <output>.partial-<id> unique sur l’hôte. En cas d’échec de la livraison, les fichiers reçus restent dans le chemin de récupération indiqué, tel que <output>.recovery-<id>, et les fichiers d’origine de l’invité sont conservés. Laissez le bac à sable en cours d’exécution et suivez la procédure de récupération associée à l’erreur avant de réessayer ou de fermer le bac à sable. Un fichier partiel conservé n’est pas nécessairement une vidéo lisible.

Les captures d’écran et la vidéo peuvent contenir des informations sensibles. Gérez le répertoire frame avec la même attention que le MP4. Consultez ui record pour les options d’enregistrement et les champs de résultats.

Inspection du bac à sable

winapp target snapshot sandbox
winapp target snapshot sandbox --json

Cela signale la préparation, les déploiements actuels et les fenêtres invitées sans créer de machine virtuelle, reconnecter le client ou réparer l’agent. Si aucun bac à sable n’est en cours d’exécution, il le signale et se termine correctement. Pour en démarrer un, utilisez winapp run . --on sandbox --detach.

Le rapport distingue ce que l’invité prend en charge par rapport à ce que le client actuel peut faire ; un client réduit peut empêcher l’entrée ou la capture même lorsque l’invité prend en charge les deux. Utilisez la liste des fenêtres invitées pour les PID de l’interface utilisateur, et non le processus lanceur suivi par un déploiement. Le champ JSON workRoot (indiqué comme Work root dans la sortie de texte) est la base absolue des chemins de transfert de fichiers relatifs, normalement C:\WinApp\work. Il est séparé de capabilities.managedRoot, normalement C:\WinApp, et est omis lorsque l’invité ne signale pas sa racine managée. Si plusieurs fenêtres clientes empêchent une capture sans ambiguïté, le message d’erreur liste les fenêtres candidates ; décidez lesquelles fermer avant de réessayer.

Exécution de commandes et copie de fichiers

winapp target exec sandbox -- dotnet --info
$copy = winapp target push sandbox .\setup.ps1 Setup\setup.ps1 --json | ConvertFrom-Json
winapp target exec sandbox --cwd (Split-Path -Parent $copy.targetPath) -- powershell -ExecutionPolicy Bypass -File .\setup.ps1
winapp target pull sandbox Results .\results

Utiliser target exec pour l’installation et les diagnostics. Il s’exécute en tant qu’utilisateur invité, transfère les flux standard et retourne le code de sortie de la commande. Il ne s’agit pas d’un terminal entièrement interactif ; les applications en mode console ont accès à des tubes redirigés. --json formate les erreurs de winapp, et non la sortie standard (stdout) de la commande enfant.

Pour push et pull, les chemins cibles sont relatifs au workRoot indiqué par target snapshot. Les chemins cibles absolus, rootés et UNC sont refusés. Un seul fichier atterrit exactement à la destination que vous nommez ; un répertoire conserve sa structure sous cette destination. Utilisez le chemin invité résolu imprimé après un push (JSON targetPath) pour choisir les commandes --cwdsuivantes ; pour un seul fichier, utilisez son répertoire parent. Si l’invité ne signale pas sa racine managée, l’envoi (push) échoue avant la copie ; suivez les instructions de mise à jour de l’erreur plutôt que d’assumer un chemin d’accès par défaut.

Exécutez uniquement des scripts d’installation que vous approuvez. L’exemple utilise l'étendue -ExecutionPolicy Bypass du processus, car un nouvel objet bac à sable refuse normalement les scripts dans sa politique Restricted.

Les transferts ignorent les fichiers inchangés et vérifient les remplacements avant de les publier. Les liens symboliques et les jonctions ne sont pas suivis : le déploiement les rejette, tandis que les copies d’annuaire ignorent les entrées liées. Une source liée nommée directement ou un chemin de destination via un lien est refusé. Copiez plutôt les fichiers ou répertoires réels.

Suppression d’une application et fin du bac à sable

winapp unregister --on sandbox --manifest .\Package.appxmanifest

Avec un fichier manifeste dans le répertoire courant, vous pouvez omettre --manifest. Cela supprime uniquement le package de développement correspondant enregistré par winapp dans le sandbox actuel. Un package installé en externe est laissé seul, même si son identité correspond. --force n’est pas pris en charge avec --on; il ne peut pas contourner les vérifications de propriété. Il s’agit d’un nettoyage de package basé sur un manifeste, et non d’une commande de désinscription pour les applications non empaquetées ou une .cs entrée.

The Sandbox reste en cours d’exécution, même après avoir fermé sa fenêtre. Gérez son cycle de vie avec sa propre interface en ligne de commande (CLI) de Windows Sandbox :

wsb list
wsb connect --id <id>
wsb stop --id <id>

L’arrêt supprime l’invité et son travail. Enregistrez d’abord les preuves nécessaires et obtenez le consentement de l’utilisateur avant d’arrêter une instance qu’il peut utiliser. Les commandes winapp ultérieures peuvent créer un nouveau bac à sable ; redécouvrir ensuite toutes les cibles d’application.

Résolution des problèmes

Suivez les indications de l’erreur nextCommand ; un avertissement userAction est une suggestion, et non une autorisation de l’exécuter automatiquement. Dans l’automatisation, inspectez la structure error.code. Les défaillances d’infrastructure peuvent se terminer avec le code 70, mais une application quelconque peut également renvoyer 70 ; le seul code de sortie numérique ne permet pas de les distinguer.

Les commandes de récupération suggérées par les opérations d’interface utilisateur routées conservent --on <target>, de sorte que la copie d’une suggestion la conserve sur la même cible d’exécution.

Erreur ou symptôme Procédure à suivre
sandbox_unsupported Vérifier Windows édition/version et la virtualisation des microprogrammes
sandbox_setup_required Activez Windows bac à sable à l’aide des instructions ci-dessus, puis redémarrez quand vous êtes prêt
sandbox_setup_requires_restart Windows signale un redémarrage en attente ; enregistrez le travail et redémarrez quand vous êtes prêt, puis réessayez
sandbox_setup_incomplete Ouvrez Windows bac à sable à partir du démarrage et terminez la configuration/la mise à jour du client, puis réessayez
sandbox_unmanaged_instance, sandbox_target_ambiguous Inspectez les instances/fenêtres signalées ; ne pas arrêter le travail non lié pour résoudre l’ambiguïté
sandbox_input_not_ready, sandbox_no_interactive_session Restaurer le client existant ou se reconnecter comme indiqué, puis réessayer
sandbox_agent_incompatible Tenez compte du message d’erreur de version ; mettez à niveau le CLI installé à l’aide de sa méthode d’installation si nécessaire. S’il vous demande d’arrêter le Sandbox, enregistrez le travail dont vous avez besoin, puis exécutez wsb stop --id <id> (avec consentement) et réessayez ; la fermeture de sa fenêtre ne l’arrête pas
sandbox_transport_failed Suivez le userAction de l’erreur. Si un partage de dossiers a échoué avec 0x80070005, Windows Sandbox (qui partage les dossiers en tant que compte SYSTEM) ne peut pas lire le dossier signalé ; accordez l’accès, puis réessayez : icacls "<folder>" /grant "*S-1-5-18:(OI)(CI)F" (S-1-5-18 est SYSTEM)
sandbox_agent_busy Attendez la fin d’une autre commande, puis réessayez
sandbox_terminated, sandbox_target_stale, sandbox_stale_handle Relancer l’application et redétecter les PID et fenêtres du système invité
sandbox_state_unavailable Vérifiez que %USERPROFILE%\.winapp\state est accessible en écriture, ou corrigez WINAPP_TARGET_STATE_ROOT s’il est défini
« Une seule instance de Windows Sandbox peut être exécutée » lors de l’ouverture de Windows Sandbox à partir du menu Démarrer Un Sandbox est déjà en cours d’exécution et Start ne peut pas s’y attacher. Basculez vers Windows Sandbox dans la barre des tâches. S’il n’a pas de fenêtre, exécutez wsb list, puis wsb connect --id <id>
sandbox_deployment_dirty, sandbox_transfer_interrupted Réessayez le déploiement ou le transfert
sandbox_runtime_provision_failed Résolvez la dépendance nommée ou la configuration du runtime non prise en charge ; voir Runtimes partagés
sandbox_package_conflict, sandbox_provisioned_package_conflict Suivez l’action spécifique au package ; ne pas supprimer les packages de boîte de réception ou non liés
sandbox_artifact_failed Vérifiez le résultat signalé et l’état de préparation du client ; préservez tout élément de preuve partiel
target_invalid, target_invalid_arguments Corriger la cible ou les options affichées dans l’erreur

winapp update met à jour les dépendances du Kit de développement logiciel (SDK) du projet, et non l’interface CLI installée. Il n’est pas un correctif pour l’incompatibilité de l’interface CLI hôte/invité.

Partager des cibles dans la version 28000 Sandbox

La build testée 28000 Sandbox ne peut pas énumérer les cibles de partage. Testez d’autres fonctionnalités de l’application dans Sandbox, mais validez les flux Share de la source vers la cible en dehors de Sandbox.

Voir également :