Wingetで簡単！開発PCセットアップ（Windows）

# まえがき
株式会社ピーアールオー（あったらいいな！を作ります） Advent Calendar 2022の2日目になります。
前日は @PRONakahiraさんの「[Angular フォームボタンの無効について](https://qiita.com/PRONakahira/items/69e80f4ee217b3a31f9f)」でした。

# Windowsの初期セットアップが面倒
職場でもプライベートでも定期的に発生するのが開発用PCの移行作業です。通常はそれほど頻繁じゃないし、大した手間じゃないと思われてる方も多いと思うんですが、なぜかこうしたPCの入れ替えって繁忙期に重なったりして、糞忙しい中でPCの再セットアップして開発に必要なソフトウェアをいちいちDLしてインスコして・・・という作業が地味に苦痛でした。

特に、LinuxやMacならパッケージシステムがあるから必要なパッケージ名を押さえておけばコマンド一発で導入することができますが、Windowsは一個一個ソフトウェアのDLページを探してDLしてインスコして・・・ってなりがちなのが超苦痛だったんですよね。。。
なので、よく使うソフトのインストーラーなどは個別で管理したり・・・。

WSLなどで開発環境として魅力的になってきたWindowsですが、この点がイケてないなぁーと常々思っておりました。

# 実はWindowsにもあった！パッケージ管理システム
と、ここまで不満を表明しておいて何なんですが、Windows環境にもパッケージ管理システムがあって、しかも結構使えるらしいことを（恥ずかしながら）先日知りました。
まだまだaptやdnf、homebrewみたいに洗練はされてないようですが、せっかくあるなら利用しない手はありません。ちょうど手元に新規に構築するPCがあったので、それを使ってお手軽開発環境構築を試してみたいと思います。

# どれを使う？(Winget, Scoop, Chocolatey)
2022/12現在で、Windows環境で利用可能なパッケージ管理システムとして主要なものは以下があるようです。

|名前|特徴(ざっくり）|
|:-----------|:-----------|
|[Winget](https://github.com/microsoft/winget-pkgs)|Microsoft製。最近正式版になったらしい。この3つの中では最も新しいので、対応パッケージがまだ少ない模様|
|[Scoop](https://scoop.sh/)|管理者権限不要でインストール可能でちょっと特殊な感じ|
|[Chocolatey](https://chocolatey.org/)|結構古くからあり、GUIがあったりと機能豊富。対応パッケージもかなり多い|

今回はまだまだ発展途上ながら、純正ツールであるWingetの使用感を確かめておきたいので、Wingetを使用することにしました。
（本当は対応パッケージが多いChocolateyを使うともっと楽が出来そうな気はするんですが、ちょっと気がかりな点もあるのでまずはWingetで様子見です。）

# 実はデフォルトで入ってる（場合もある）。
これも知らなかったんですが、WingetはWindows 10 1709 (ビルド 16299) 以降のWindows10, Windows11であればインストールされているようです。実際私のWindows10環境でも入れた覚えはないですが、wingetが利用可能でした[^1]。

```
> winget -v
v1.3.2691
```

ただ、Windows11であってもバージョンによっては入ってない場合もあるそうで、その場合はWindows Updateにより入ることがあるようです。（今回、新規移行先のPCがまさにこれだった）

入ってない場合はMicrosoft storeアプリから「アプリインストーラー」をインストールすれば導入可能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221091/3b2869a7-0394-5789-b0cc-9b9be763235d.png)


# 環境移行に便利な機能
## インストールソフトウェア情報のエクスポート
Wingetは既存環境から構成情報をエクスポートすることができ、これが結構便利な気がしました。
やり方は簡単。移行元のPCで以下を実行するだけです。

```
winget export -o C:\install_softwares.json
```

この時、おそらくこんなメッセージが大量に出力されると思います。これはWingetのリポジトリに未登録のソフトが検出されたときに出てくるようです。したがって、ここで利用できないとされたソフトについては手動でインストールする必要があります。

```
インストールされているパッケージのバージョンは、どのソースからも利用できません: A5:SQL Mk-2
インストールされているパッケージのバージョンは、どのソースからも利用できません: dynabook PC Information
インストールされているパッケージのバージョンは、どのソースからも利用できません: dynabook Settings
```


出力された情報はこんな感じです。思ったより簡素・・・

```
{
	"$schema" : "https://aka.ms/winget-packages.schema.2.0.json",
	"CreationDate" : "2022-12-01T18:03:55.590-00:00",
	"Sources" : 
	[
		{
			"Packages" : 
			[
				{
					"PackageIdentifier" : "Mattermost.MattermostDesktop"
				},
				{
					"PackageIdentifier" : "Microsoft.VisualStudio.2019.Community"
				},
				{
					"PackageIdentifier" : "Microsoft.VisualStudio.2022.Community"
				},
				{
					"PackageIdentifier" : "Docker.DockerDesktop"
				},
				{
					"PackageIdentifier" : "GIMP.GIMP"
				},
				{
					"PackageIdentifier" : "Git.Git"
				},
				{
					"PackageIdentifier" : "Google.Chrome"
				},
				{
					"PackageIdentifier" : "Inkscape.Inkscape"
                (省略）
```

exportコマンドは、インストールされているもので使用可能（=リポジトリに登録されている）なソフトウェアをすべて出力するので、もう不要なものなどは手動で管理してあげた方がよさげです。

特に、以下のようにVisual C++の再頒布可能パッケージは複数出てくる可能性がありますが、どれが実際に必要なのか？は分からないので[^2]、急ぎであれば目をつぶって全部入れるか、あるいは全部消して必要なものだけを厳選するかは、移行の時にどれくらい時間が割けるかで検討した方が良さそうです。

```
				{
					"PackageIdentifier" : "Microsoft.VCRedist.2010.x64"
				},
				{
					"PackageIdentifier" : "Microsoft.VCRedist.2015+.x64"
				},
				{
					"PackageIdentifier" : "Microsoft.VCRedist.2012.x86"
				},
				{
					"PackageIdentifier" : "Microsoft.VCRedist.2008.x64"
				},
				{
					"PackageIdentifier" : "Microsoft.VisualStudioCode"
				},
				{
					"PackageIdentifier" : "Microsoft.VCRedist.2015+.x86"
				},
				{
					"PackageIdentifier" : "Microsoft.VCRedist.2013.x86"
				},
```

## インポート
出力されたjsonは、移行先のPCにてimportを行うことで一発でインストールが行えます。

```
winget import (path_to_json)
```

注意すべき点として、実行する際のコマンドプロンプトは管理者権限で開いた方が良さそうです。そうでないとインストール中にUAC（ユーザーアカウント制御）が必要なものはダイアログが表示され、待機状態になってしまうためです。

そこさえ注意すれば、UIインストーラーなどは自動的に起動し、インストールプロセスも自動で進行するので[^3]、基本放置が可能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221091/52ea62e9-4680-4318-ba01-34f90aa287d0.png)

また、Wingetはバージョンを指定してのインストールも行えるはずですが、上記のやり方では基本としてリポジトリに登録されている最新版がインストールされることになります。
(jsonファイルを用いてのバージョン指定インポートのやり方については現状わかりませんでした。出来る気はするのですが・・・）

# そのほかの使い方
## ソフトウェアを検索する

```
winget search (キーワード)
```

結果はこんな感じで出てきます。
※大文字小文字の違いは無視されるようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221091/d05e27a8-34f2-5b4a-87fc-aad87723d241.png)

## ソフトウェアの詳細情報を表示する
```
winget show (パッケージid)
```
こんな感じで表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221091/45263090-59ee-2ca5-a0b5-b9f804fa66e7.png)
複数バージョンがある場合には、--versionsを指定すれば見ることができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221091/c47500a1-ae45-4224-da16-406f4d2c1435.png)


## ソフトウェアのインストール
```
winget install (パッケージid)
```
showコマンドも同じですが、パッケージ名（id）は完全一致する必要があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221091/01b1b821-cc16-5000-a519-bdc713e9e99a.png)

※バージョンを指定する場合には--versionを指定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221091/11afe8bc-31e2-3c42-9c42-f2be344adf9e.png)

## ソフトウェアの更新
```
winget upgrade (パッケージid)
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221091/e4c58c84-2bb4-cfb0-50f9-e4944acb3e89.png)

## ソフトウェアの削除（アンインストール）
```
winget uninstall (パッケージid)
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221091/420fd6d7-9e9a-9c05-402f-8a7d3679174e.png)

## インストール済みのソフトウェアを表示する
```
winget list
```
インストールされているソフトウェアの一覧を表示します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221091/0d3a09f7-9040-d26d-e44c-7dbb95d9dc9c.png)
一つ注意すべきは、ここで表示されるリストはWingetのリポジトリに登録があるなし関係なく、対象のPCにインストールされているソフトウェアを一覧として表示します。したがってlistで表示されたものがインストール可能ではありません。

# その他注意すべき点など
## インストールされるソフトウェアの信頼性について
Wingetのリポジトリは、[github](https://github.com/microsoft/winget-pkgs)にて管理されていますが、ここで管理されている情報（マニフェスト）は要はどのソフトウェアのインストーラーがどこのURLにあるか？という情報です。
しかも、このマニフェストは誰でもプルリクを送ることができます（そのソフトウェアに関係のない第三者でも）。
もちろん登録にあたっては真偽性の確認などは行われているとは思うのですが、プロセス的に攻撃の可能性を排除しきれないところに一抹の不安を感じます。
実はこの問題はWingetに限った話ではなく、Chocolateyなどの他のパッケージ管理システムでも同様の事情があるようです[^4]。
なので、利用にあたっては注意が必要になるし、職場などで利用するにあたっては事前の確認・許可などは必要と思います[^5]。

## 依存性について
パッケージ管理システムのくせに依存性解決してくれないのか～、とお嘆きの方は多いと思います（私もです）。
が、これについては現在検討が進められているようで、それこそaptやらdnfやらを参考に依存性解決の仕組みを導入することを検討するそうです。
今後に期待ですね。

[^1]: もしかしたら過去にWindows Insider programを適用していたからかも知れません。真偽はもはやわからないので、wingetが入ってなかったら素直にMicrosoftストアからインストールしてください。

[^2]: 本文中でも触れましたが、Wingetは依存性の解決がまだ行えないため、必要なライブラリかどうかは分からないし、インストール時にも自動で入れてくれたりないと思った方がよいです（ただ、.NETフレームワークについては必要なバージョンのインストールを求められますが）。

[^3]: Wingetに限った話ではないですが、Windowsのパッケージ管理システムでは基本標準構成インストールのみしか行えません。よくGUIのインストーラーでカスタム設定などが行える奴がありますが、そういったきめ細やかな設定は基本出来ないと思って使った方が良いです。したがって、カスタムインストールが必要なソフトについてはこうした仕組みを使っての導入は避けた方がいいです。

[^4]: このため、今回はChocolateyではなくWingetを使いました。Microsoft謹製だからセキュア・・・というわけではないですが、やはり標準ツールを使う方が気持ち的な安心感があるのと、いざ何かあった時の怒られ度合いが違うかな・・・と思ってのことです。（今回試したのは私用PCですがｗ）

[^5]: [こんなこと](https://japan.zdnet.com/article/35131723/)もあったので、Linuxとて決してセキュアなわけではないですが。。。