Windows サンドボックスの実行

コンピューター上にビルドし、Windows サンドボックスでアプリを実行して自動化します。

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

MyAppは、アプリ名またはrunで出力されたゲスト PID に置き換えます。 --detach は起動後に戻り、次のコマンドでアプリを検査できます。ない場合、 run はアプリが終了するまで待機します。 サンドボックスは、コマンドとリビルドの間で実行され続けています。

始める前に

  • ハードウェア仮想化を有効にして、サポートされているエディションで Windows 11 24H2 以降を使用します。
  • ゲスト winapp では、x64 と Arm64 がサポートされます。 x86 アプリでは、アプリを実行し、x86 の依存関係を照合するためのゲスト サポートが必要です。x64 ランタイムが x86 アプリを満たしていません。
  • 実際の入力と画面キャプチャのために、ホスト セッションのロックを解除したままにします。

[Windows機能のオンとオフを切り替える] でWindowsサンドボックスを有効にするか、管理者ターミナルからこれを実行します。

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

作業内容を保存し、準備ができたらWindowsを再起動します。 次に、[スタート] メニュー Windowsサンドボックスを開き、クライアントのインストールまたは更新を完了します。 winapp では、この機能の有効化、クライアントのインストール、昇格の要求、Windowsの再起動は行われません。 前提条件がない場合は、セットアップ手順で停止します。保留中のWindows再起動が個別に報告されます。

コールド接続または再接続は、短時間集中できます。 接続されると、winapp はアクティブ化せずに、独自のクライアント ウィンドウを画面から離したままにします。 自分で開いたサンドボックス ウィンドウはそのまま残ります。

Important

ビルドは引き続きコンピューター上で実行されます。 Projectの評価、復元、コンパイルは分離されません。 --on sandbox では、信頼されていないプロジェクトを安全にビルドすることはできません。

1 つのサンドボックスは、1 つの共有環境です。 その中のアプリとワークフローは、ユーザー、デスクトップ、レジストリ、パッケージ、ランタイム、ネットワーク アクセスを共有します。 互いに観察したり干渉したりする可能性があります。 相互に信頼されていないワークフローには、個別のマシンを使用します。

Windowsでは、一度に 1 つのサンドボックスが許可されます。 winapp は、自分で開いたインスタンスを含め、実行中のインスタンスを再利用します。 これを準備すると、winapp の共有ブートストラップ フォルダー、ゲスト エージェント、開発者モード、受信ファイアウォール規則が追加されます。 winapp は、採用されたインスタンスを停止したり、関連のないアプリを削除したりすることはありません。 サイレント ホスト フォールバックはありません。サンドボックスを要求するコマンドがそこで実行されるか、失敗します。

実行と再構築

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

--configuration、--arch、--framework、--property、--no-build、--no-restoreなどのビルド オプションがホストに適用されます。 登録、起動、デバッグはゲストで行われます。アプリがコンピューターに登録されていません。

オプション サンドボックスでの効果
--detach 終了を待つのではなく、起動後に戻る
--no-launch 起動せずにデプロイして登録する
--clean この展開を再インストールし、アプリケーション データをクリアする
--unregister-on-exit アプリの終了後にこのパッケージの登録を削除する
--with-alias 転送されたストリームを使用してゲスト実行エイリアスを起動する
--debug-output ゲスト デバッグ出力をストリーミングする。 パッケージ アプリのみ

パッケージ化されていないアプリは、展開されたフォルダーから実行可能ファイルを起動します。 登録するパッケージがありません。 --debug-output は、パッケージ化されていないサンドボックスの実行では拒否されます。

再実行により、変更されたファイルが転送され、ビルド出力から削除されたファイルが削除されます。 アプリケーション データは、 --cleanを要求しない限り保持されます。 不完全なデプロイは起動しません。再試行すると、ゲスト コピーが再構築されます。 winapp で準備中にビルド ファイルが変更された場合は、ビルドを完了して再試行します。

ウォーム UI コマンドは、サンドボックス準備メッセージを繰り返さずに結果のみを報告します。 サンドボックスの起動と接続の回復は、引き続き進行状況を報告します。 接続タイミングと診断の詳細を表示するには --verbose を使用します。進行状況表示を抑制するには --quiet と --json を使用します。 JSON の実行には、ゲスト プロセス ID とターゲット スコープが含まれます。

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

これらは、個別のドキュメントではなく、実行結果の追加フィールドです。 アプリを検査するときに UiTargetArgs 値全体をコピーします: winapp ui inspect --on sandbox -a 4212。 サンドボックスが再作成された後に、PID とウィンドウ ハンドルを再検出します。ホストや将来のゲストではなく、サンドボックスの世代に属します。

デタッチされたアプリとエージェントの有効期間

エージェントの修復中など、ゲスト エージェントが停止すると、デタッチされた パッケージ化されていない アプリが終了します。 コマンド間で非表示になる場合は、 --detach を使用して再実行し、その UI ターゲットを再検出します。 デタッチせずにアプリの終了を待つことで、その終了を確認できますが、エージェントが失われてもアプリが存続できるようになるわけではありません。 パッケージ アプリでは、エージェントのプロセスの有効期間ではなく、Windowsアクティブ化が使用されます。 サンドボックスを閉じるか再起動すると、サンドボックス内のすべてのアプリが終了します。

共有ランタイム

winapp は、起動前にアプリのパッケージの依存関係、Windows アプリ SDK要件、および*.runtimeconfig.jsonを確認します。 ホスト キャッシュを使用するか、必要なペイロードをダウンロードし、マシンではなく、サポートされていないランタイム をゲストにインストールします。

パッケージの要件には、発行元、バージョン、アーキテクチャが含まれます。 共有.NETランタイムの選択では、アプリケーションで構成されているロールフォワード ポリシーとアーキテクチャが優先されます。同じメジャー バージョンの新しいランタイムが機能するとは想定しません。

フレームワーク、ランタイム構成、または依存関係をサポートできない場合、コマンドは起動前に明示的に失敗し、要件を識別します。 そのエラーの対処方法に従ってください。 プロジェクトでサポートされている場合、自己完結型の発行では、対応する共有ランタイムが不要になります。関連付けられていないパッケージの依存関係は削除されません。

UI の自動化

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

すべての ui 動詞は --on sandboxを受け入れます。 アプリ名、PID、ウィンドウ ハンドル、セレクターはゲスト内で解決されます。 アプリを対象とするコマンドには -a/--app または -w/--window を使用します。winapp では、最後に起動されたアプリは推測されません。 --on sandbox省略すると、代わりにホスト デスクトップが選択されます。

実際の入力と記録には 、接続された、ミニマイズされていないサンドボックス クライアントが必要です。 読み取り専用検査は、入力できない場合でも機能します。 winapp は、ライセンス認証なしで、最小化された独自のクライアントを復元できます。最小化された手動で開かれたクライアントは、ユーザーが復元する必要があります。 再接続後に入力を利用できない場合、コマンドは入力を渡したと主張するのではなく、失敗します。 エラーで再接続コマンドを使用して、再試行します。

winapp target snapshot sandbox --jsonを使用して、サンドボックスを起動または再接続せずにデスクトップの準備状況を確認します。 認識されたターミナル エラー ウィンドウは、リモート デスクトップとしてカウントされません。 winapp が、まだ接続中であるか検査できないために、選択したデスクトップを検証できない場合、準備完了状態は利用不可のままです。しばらく待ってから再試行してください。 複数のリモート デスクトップがあいまいな場合があります。 スナップショットによってウィンドウが閉じたり、エラーが解決されたりすることはありません。

セレクター、入力メソッド、アサーションの UI オートメーション を参照してください。

サンドボックスでの UI ワークフローの調整

コマンドを連携するために 1 つの WINAPP_UI_WORKFLOW_ID を使用し、独立したワークフローごとに異なる値を使用します。 それを呼び出しのたびに設定してください。特に、エージェントが各ツール呼び出しごとに新しいシェルを開始する場合はそうしてください。 winapp は、ハッシュされたサンドボックス生成固有の ID を転送します。生のホスト値はゲストに送信されません。

たとえば、同じ値を使用して 2 つのターミナルで記録と対話を行います。 新しいワークフローごとに新しい値を選択します。

ターミナル 1:

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

ターミナル 2、記録の実行中:

$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

記録とアクションの 両方 が完了したら、

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

名前付きワークフローでは、最後のコマンドの後に 4 秒間 UI ターンが保持されます。 yield はすぐに解放されます。 ID を指定しない場合、各コマンドは完了時にその順番を解放します。 そのため、no-ID 記録は、デスクトップを変更する他のワークフローをその期間ブロックします。 読み取り専用の検査は待たずに実行されます。 ホストとゲストの UI ターンは別々です。

一時停止後、もう一度検査し、必要なメニューまたはダイアログをもう一度開きます。別のワークフローがゲスト デスクトップを使用している可能性があります。 協調ターンでは、アプリが互いに分離されません。

スクリーンショットと記録

アプリのウィンドウuiキャプチャを使用するか、シェルとインストーラーダイアログを含むネイティブ ゲスト デスクトップ全体のtargetキャプチャを使用します。

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

出力は、-oを省略した場合を含め、ホスト上に置きます。 スクリーンショットは既定で screenshot.png。記録には recording-<timestamp>-<guid>.mp4が使用されます。 記録の場合、--framesは JPAG、frames.ndjson、およびmanifest.jsonを含む<output-name>.frames ディレクトリも配信します。 結果にはホスト パスが表示されます。 ターゲットレコーディングはゲストで実行されます。記録が完了し、配信が完了すると、ホスト ファイルが使用可能になります。

target screenshot は、ウィンドウをアクティブ化せずにゲストの UI ターンを待機します。 ホスト サンドボックス ウィンドウのタイトル バーと境界線は除外されます。 その PNG は拡大・縮小されません。ゲスト画面の原点を (0,0) とすると、画像座標は --on sandbox を用いて、ui drag や ui touch --at などの座標入力系の動詞でそのまま使用できます。 配信元がマイナスとなるデスクトップについて、報告された配信元を追加します。 --jsonを使用してcoordinates.sourceBoundsとcoordinates.contentRectを読み取ります。物理ピクセルと排他的な右/下端の両方を使用します。

ターゲットの記録では、JSON とフレーム マニフェストの同じフィールドが報告されます。 MP4 フレームと JPEG フレームは、 --max-edge スケーリングやエンコーダーパディングなど、マッピングを共有します。 画像ピクセル (x,y)をマップするには、最初に contentRect外のポイントを拒否してから、各ソース座標を sourceStart + floor((pixel - contentStart + 0.5) * sourceSize / contentSize)として計算します。 ダウンスケールでは精度が失われます。正確な座標が重要な場合はネイティブ PNG を使用します。 ゲスト デスクトップの境界を変更すると、 display_changedで記録が停止され、変更前のフレームのみが保持され、フレーム マニフェストが部分的にマークされます。

既存の MP4 またはペアの .frames ディレクトリは、既定で拒否されます。 新しいパスを使用するか、新しいテイクが終了したらそれらを置き換えるために --overwrite を渡してください。 以前のフレーム バンドルは、置換によって--framesが省略された場合を含め、<output-name>.frames.previous-<id>として保持されます。 失敗したキャプチャでは、古い記録はそのまま残ります。

スクリプトとエージェントには肯定的な --duration-sec を使用します。 npm uiRecord および targetRecord ヘルパーには durationSecが必要です。中止シグナルは、グレースフル ストップとしてではなく、強制的にキャンセルされます。 サポートされている値については、 ui record を参照してください。 CLIで継続時間を指定しない場合、記録は停止信号を待ちます。

キャプチャの開始後に Ctrl + C キーを押して、 stopReason: cancelledを使用して正常に記録を完了して返すことができます。 その他の中断は、便利なビデオやフレームを保持できます。 存在する場合は、 stopReason、 partialOutput、および recoveryHint を読み取り、通常の完了を想定するのではなく、報告された証拠のパスを使用します。 取得中にデスクトップ全体のキャプチャが使用できなくなった場合は、使用できないデスクトップをキャプチャし続けるのではなく、 capture_unavailable で停止します。 フレームを復旧するためにサンドボックスを前面に表示しません。 使用可能な証拠が使用可能になる前に、キャプチャが失敗する可能性があります。

ゲストの記録に失敗した場合、回復された証拠はホスト上の一意の <output>.partial-<id> ディレクトリに配置されます。 配信に失敗した場合、受信したファイルは報告された回復パス ( <output>.recovery-<id>など) の下に残り、ゲストの元のファイルは保持されます。 サンドボックスを実行したまま、再試行または終了する前にエラーの復旧アクションに従います。 保存された部分ファイルは、必ずしも再生可能なビデオであるとは限りません。

スクリーンショットやビデオには機密情報が含まれている場合があります。 MP4 と同じ注意を払ってフレーム ディレクトリを処理します。 記録オプションと結果フィールドについては、 ui record を参照してください。

サンドボックスの検査

winapp target snapshot sandbox
winapp target snapshot sandbox --json

これにより、VM の作成、クライアントの再接続、エージェントの修復を行わずに、準備状況、現在のデプロイ、ゲスト ウィンドウが報告されます。 サンドボックスが実行されていないと、その事実が報告され、正常に終了します。 開始するには、 winapp run . --on sandbox --detachを使用します。

このレポートでは、ゲストがサポートしているものと、現在のクライアントが実行できることが区別されます。最小化されたクライアントは、ゲストが両方をサポートしている場合でも、入力またはキャプチャを防ぐことができます。 UI ID にはゲスト ウィンドウの一覧を使用します。デプロイの追跡されたランチャー プロセスには使用しません。 JSON workRoot フィールド (テキスト出力で Work root として表示) は、通常は C:\WinApp\work相対ファイル転送パスの絶対ベースです。 これは、通常はC:\WinAppcapabilities.managedRootとは別であり、ゲストがマネージド ルートを報告しない場合は省略されます。 複数のクライアント ウィンドウがあるために対象を一意に特定してキャプチャできない場合、エラーメッセージに候補が一覧表示されます。再試行する前に、どれを閉じるか判断してください。

コマンドの実行とファイルのコピー

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

セットアップと診断には target exec を使用します。 ゲスト ユーザーとして実行され、標準ストリームが転送され、コマンドの終了コードが返されます。 完全な対話型ターミナルではありません。コンソール アプリケーションには、リダイレクトされたパイプが表示されます。 --json は、子コマンドの stdout ではなく winapp エラーを書式設定します。

pushとpullの場合、ターゲット パスは、target snapshotによって報告されるworkRootに対して相対的です。 絶対パス、ルートパス、UNC ターゲット パスは拒否されます。 1つのファイルは、あなたが名前を付け、正確に宛先に到着します。ディレクトリは、その宛先の下の構造を保持します。 プッシュ後に出力される解決済みのゲスト パス (JSON targetPath) を使用して、次のコマンドの --cwdを選択します。1 つのファイルの場合は、その親ディレクトリを使用します。 ゲストがマネージド ルートを報告しない場合、コピー前にプッシュが失敗します。既定のパスを想定するのではなく、エラーの更新ガイダンスに従ってください。

信頼できるセットアップ スクリプトのみを実行します。 この例では、プロセス スコープの -ExecutionPolicy Bypass を使用します。新しいサンドボックスでは、通常、 Restricted ポリシーの下でスクリプトが拒否されるためです。

転送時には、変更のないファイルはスキップされ、置換内容は公開前に確認されます。 シンボリック リンクとジャンクションはフォローされません。デプロイでは拒否されますが、ディレクトリ コピーではリンクされたエントリがスキップされます。 直接指定されたリンクされたソースまたはリンク経由の宛先パスは拒否されます。 代わりに、実際のファイルまたはディレクトリをコピーします。

アプリの削除とサンドボックスの終了

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

現在のディレクトリにマニフェストがある場合は、 --manifestを省略できます。 これにより、現在のサンドボックスで winapp によって登録された一致する開発パッケージのみが削除されます。 外部にインストールされたパッケージは、ID が一致する場合でも、単独で残ります。 --force は、 --onではサポートされていません。所有権チェックをバイパスすることはできません。 これはマニフェスト ベースのパッケージのクリーンアップであり、パッケージ化されていないアプリや .cs 入力の登録解除コマンドではありません。

サンドボックスは引き続き実行されます。 Windowsサンドボックス独自の CLI を使用して、その有効期間を管理します。

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

停止すると、ゲスト環境とその作業内容は破棄されます。 必要な証拠を最初に保存し、使用しているインスタンスを停止する前にユーザーの同意を得る。 後で winapp コマンドを実行すると、新しいサンドボックスを作成できます。その後、すべてのアプリ ターゲットを再検出します。

Troubleshooting

エラーの userAction に従ってください。nextCommand の勧告は提案であり、自動実行してよいという許可ではありません。 自動化では、構造化された error.codeを調べます。 インフラストラクチャの障害は 70終了する可能性がありますが、任意のアプリケーションが 70を返すこともできます。数値の終了状態だけでは区別されません。

ルーティングされた UI 操作によって提案された回復コマンドでは --on <target> が保持されるため、提案をコピーしても同じ実行ターゲットのままになります。

エラーまたは症状 何をすべきか
sandbox_unsupported Windows のエディション/バージョンとファームウェアの仮想化設定を確認してください
sandbox_setup_required 上記の手順Windows使用してサンドボックスを有効にしてから、準備ができたら再起動します
sandbox_setup_requires_restart Windows で再起動が保留中と報告されています。作業内容を保存し、準備ができたら再起動してから、もう一度お試しください。
sandbox_setup_incomplete [スタート] から Windows Sandbox を開き、クライアントのセットアップ/更新を完了してから、再試行します
sandbox_unmanaged_instance、sandbox_target_ambiguous 報告されたインスタンス/ウィンドウを検査します。あいまいさを解決するために関連のない作業を停止しない
sandbox_input_not_ready、sandbox_no_interactive_session 既存のクライアントを復元するか、指示に応じて再接続してから、再試行してください
sandbox_agent_incompatible バージョンエラーに従ってください。必要に応じてインストール方法を使用してインストール済みの CLI をアップグレードし、同意がある場合にのみ閉じる/再試行する
sandbox_agent_busy 別のコマンドが完了するのを待ってから、再試行してください
sandbox_terminated、sandbox_target_stale、sandbox_stale_handle アプリを再実行し、ゲスト PID/windows を再検出する
sandbox_state_unavailable %USERPROFILE%\.winapp\state が書き込み可能であることを確認するか、設定されている場合は WINAPP_TARGET_STATE_ROOT を修正してください
sandbox_deployment_dirty、sandbox_transfer_interrupted デプロイまたは転送を再試行する
sandbox_runtime_provision_failed 名前付き依存関係またはサポートされていないランタイム構成を解決します。「共有ランタイム」を参照してください
sandbox_package_conflict、sandbox_provisioned_package_conflict パッケージ固有のアクションに従います。関連のないパッケージまたは受信トレイ パッケージを削除しない
sandbox_artifact_failed 報告された出力とクライアントの準備状況を確認します。部分的な証拠を保持する
target_invalid、target_invalid_arguments エラーに表示されるターゲットまたはオプションを修正する

winapp update は、インストールされている CLI ではなく、 プロジェクト SDK の依存関係を更新します。 これは、ホスト/ゲスト CLI の非互換性の修正ではありません。

ビルド 28000 サンドボックスでターゲットを共有する

テスト済みのビルド 28000 サンドボックスは、共有ターゲットを列挙できません。 サンドボックスで他のアプリ機能をテストしますが、外部のソースからターゲットへのフローを共有することを検証します。

参照