🍺

Windowsサンドボックスでwingetを使ってみた話

2022/01/22に公開
2

変更履歴

2022.05.18 - Microsoft.UI.Xaml.2.7 に関する記述を追加しました。

きっかけ

Windowsのクリーンインストールを実施した機会にwingetを使い始めたわけですが、

https://zenn.dev/nobokko/articles/idea_winget_show

名前を見ても知らないものも多く、特に初めて使うものはいきなりインストールする前にちょっと確認したいなって思いました。

Windowsサンドボックスとは

名前の通りですが、Windowsのサンドボックス(仮想環境)です。

現状たぶん公式にはHomeでは使えません。(正しくはサポートされていません、使う方法はあるようですが合法かどうか知りません)

Proであれば、設定>アプリ>オプション機能>Windowsのその他の機能>Windowsサンドボックス のチェックを入れて再起動すると使用可能な状態になります。

ググれば導入方法は色々出てくるので情報には困らないと思います。

仕事では

  • インストールの手順書の作成を依頼されたけど、ローカルには既にインストール済みで困った
  • このサイト、URLが不穏だけどアクセスしても大丈夫かな

なんて時に使えると思います。

Windowsサンドボックスでwinget

Windowsサンドボックスを起動しただけでは使えませんという話

最近のWindowsアップデートを行っているWindows10(と知らんけどWindows11)であればwinget、もしくはwinget.exeをDOSやPowerShellでタイプするだけで使えるのですが、Windowsサンドボックスで同じことをすると、

winget : The term 'winget' is not recognized as the name of a cmdlet, function, script file, or operable program.
Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At line:1 char:1
+ winget
+ ~~~~~~
    + CategoryInfo          : ObjectNotFound: (winget:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

要は未導入な状態のようです。

Windowsサンドボックスにwingetを導入しよう!という話

https://github.com/microsoft/winget-cli

まず、
Microsoft Store [Recommended]
なのですが、WindowsサンドボックスにはMicrosoft Storeがありませんでした。この方法は使えません。

したがって
Manually Update
こちらを読みましょう。

https://github.com/microsoft/winget-cli/releases

(Latestを一応推奨しておきます)のAssetsと書いている部分をクリックするといくつかのリンクが表示されます。

必要になるのは拡張子が「msixbundle」のファイルです。ダウンロードします。
クリックしてインストーラが起動すればよいのですが、おそらく何にも関連付けされていない状態(真っ白なアイコン)かと思います。

You may need to install the VC++ v14 Desktop Framework Package.
と書いてある部分には古い環境でエラーがあるなら、という旨のことが説明されていますが、本件でも有効でした。

https://docs.microsoft.com/ja-jp/troubleshoot/cpp/c-runtime-packages-desktop-bridge#how-to-install-and-update-desktop-framework-packages

の拡張子が「appx」のファイルをダウンロードします。おそらくx64でよい人が多いのではないでしょうか。[1]

ダウンロードしたら、PowerShellを開いて、

Add-AppxPackage -Path 

まで入力して、ダウンロードしたファイルをD&Dすると、

Add-AppxPackage -Path C:\Users\WDAGUtilityAccount\Downloads\Microsoft.VCLibs.x64.14.00.Desktop.appx

となりました。[2]これを実行します。何も表示されずに次の入力待ちになればおそらくOKです。

引き続き、PowerShellで

Add-AppxPackage -Path 

まで入力して、ダウンロードしたファイルをD&Dすると、

Add-AppxPackage -Path C:\Users\WDAGUtilityAccount\Downloads\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle

となりました。これを実行します。こちらも何も表示されずに次の入力待ちになればおそらくOKです。

これでwingetがWindowsサンドボックスで使えるようになりました。

Windowsサンドボックスを起動時にwingetを導入しよう!という話

DockerのImageのようにwinget導入済みの状態で固めることができるとよいのでしょうが、そういう機能はWindowsサンドボックスには(おそらく)無いです。頻繁に使うのであれば毎回上記のような手順を踏むのは少々手間です。

Step1 : 上記ファイルを保存しておいて、ps1形式で実行できるようにしておくと手間が減る気がします

install-winget-env.ps1
Add-AppxPackage -Path Microsoft.VCLibs.x64.14.00.Desktop.appx

Add-AppxPackage -Path Microsoft.UI.Xaml.2.7.appx

Add-AppxPackage -Path Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle

このシェルと、上記3ファイルを同じフォルダに格納しておけば、Windowsサンドボックスを起動後にローカルからサンドボックスにコピー&ペーストしてシェルを実行するだけになります。

以前
install-winget-env.ps1
Add-AppxPackage -Path Microsoft.VCLibs.x64.14.00.Desktop.appx

Add-AppxPackage -Path Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle

このシェルと、上記2ファイルを同じフォルダに格納しておけば、Windowsサンドボックスを起動後にローカルからサンドボックスにコピー&ペーストしてシェルを実行するだけになります。

Step2 : ローカルからサンドボックスにコピペする手間を省く

Windowsサンドボックスはささやかながら起動時の設定をコントロールすることが可能です。

https://docs.microsoft.com/en-us/windows/security/threat-protection/windows-sandbox/windows-sandbox-configure-using-wsb-file#mapped-folders

Windowsサンドボックスの設定ファイルを用意することで、ローカルとフォルダ単位で共有を行うことが可能です。

shared-folder.wsb
<Configuration>
    <MappedFolders>
        <MappedFolder>
            <HostFolder>D:\windows sandbox\readonly</HostFolder>
            <ReadOnly>true</ReadOnly>
        </MappedFolder>
    </MappedFolders>
</Configuration>

上記をテキストエディタ(メモ帳でいいです)でコピペで貼り付けて「shared-folder.wsb」という名前で保存してください。普段拡張子を隠して使っている人は.txtのままでは動かないことに注意してください。

shared-folder.wsbを実行することでデスクトップにreadonlyというフォルダが配置されている状態でWindowsサンドボックスが起動します。

MappedFoldersを簡単に説明

  • MappedFoldersは複数のMappedFolderを指定可能です。
  • MappedFolderに共有するフォルダに関する情報を指定します。
  • HostFolderにはローカル側のパスを指定します。上記の場合は、Dドライブのwindows sandbox配下のreadonlyフォルダを指定していることになります。
  • SandboxFolderという項目もあります。省略した場合はデスクトップになります。
  • ReadOnlyにtrueを指定しておくとHostFolderで指定したフォルダにサンドボックス側からは書き込みが出来なくなります。

wingetをWindowsサンドボックス使用時に高頻度で使用するとは限らない場合は、このくらいの設定に留めるのが比較的汎用性が高いと思います。

Step3 : 更にシェルを実行する手間も省く

Windowsサンドボックスはささやかながら起動時の設定をコントロールすることが可能です。(二回目)

https://docs.microsoft.com/en-us/windows/security/threat-protection/windows-sandbox/windows-sandbox-configure-using-wsb-file#logon-command

Windowsサンドボックスの設定ファイルを用意することで、起動時に実行するコマンドを「一つだけ」指定することができます。
複数指定することができるのであれば直接設定に書けるのですが、ここで事前にシェルを作成しておいたことが生きてきます。

use-winget.wsb
<Configuration>
    <MappedFolders>
        <MappedFolder>
            <HostFolder>D:\windows sandbox\readonly</HostFolder>
            <ReadOnly>true</ReadOnly>
        </MappedFolder>
    </MappedFolders>
    <LogonCommand>
        <Command>powershell 
        -executionpolicy unrestricted 
        -command "start powershell -WorkingDirectory C:\Users\WDAGUtilityAccount\Desktop\readonly -WindowStyle Minimized {-noexit -file install-winget-env.ps1}"</Command>
    </LogonCommand>
</Configuration>

wingetを使う前提なので、powershellは起動したままにしてあります。

LogonCommandを簡単に説明

  • 実行ファイルや実行スクリプト(bat系)を指定します。Windowsサンドボックスで実行されるので、Windowsサンドボックスからアクセスできるファイルしか実行できないことに気を付ける必要があります。

まとめ

  • Windowsサンドボックス環境下でwingetを使うにはいくつかの作業が必要です
  • Windowsサンドボックスの設定ファイルを用意しておけば手間を最小限にできます

お疲れさまでした。

脚注
  1. よくわからない場合は全部試してください、ある意味そういうことを気軽にするためにあるのがサンドボックスだと思います。 ↩︎

  2. もちろん、D&Dではなく自分で直接入力してもOKです ↩︎

  3. 解凍ソフトが対応していればそのままでもよいかもしれません。 ↩︎

Discussion

yunb42yunb42

とても参考になりました。ありがとうございます。

ちなみにですが、下記のissue にここに書いてくださったツールのインストール及びスクリプトの作成、sandbox の起動までを行ってくれるスクリプトが記載されていました。
https://github.com/microsoft/winget-cli/issues/2081#issuecomment-1129996413

SandboxTest.ps1 をダウンロードして実行するとwinget入のsandbox が立ち上がります。もしよければ試してみてください。

のぼっこのぼっこ

スクリプトの中身を読む限り、さすがwingetの本家で作られてるだけあってwingetの設定なども何かしらやってくれてるみたいですね!

難点があるとすれば、いきなりスクリプトをPCで実行する前にちょっと確認したいなって思ってるときに
このスクリプトをsandbox上で試すのは難しそうってことでしょうか。

あとはSandboxを利用する目的次第ではあるし気にするほどでも無いかもしれませんが、普段はSandboxTest.ps1からwrite権限のあるフォルダをマップしない方がsandbox呼び出し元のPCが安全に使える気がしました。

私が使う場合は以下の行は削除

    <MappedFolder>
      <HostFolder>$mapFolder</HostFolder>
    </MappedFolder>

もしくは削除だと動かなくなりそうであれば

    <MappedFolder>
      <HostFolder>$mapFolder</HostFolder>
      <ReadOnly>true</ReadOnly>
    </MappedFolder>

とsandboxからローカルへは書き込みはさせない状態に変えて使いそうです。
(実行はしていないので処理中に何らかの書き込みが必要なのかもしれませんが……)