Windows Package Manager (Preview) メモ

# 概要

`Windows Package Manager`はWindowsのネイティブなパッケージマネージャーです。2020年5月14日に最初のプレビューがリリースされました。OSSなのでGitHubからソースコードをチェックアウトして自分でビルドすることができます。
パッケージマネージャーには、通称`winget`というPackage Manager CLIがあり、コマンドラインからアプリケーションをインストールすることが可能です。

開発のマイルストーンは[Milestones - microsoft/winget-cli] (https://github.com/microsoft/winget-cli/milestones)で確認できます。

**環境**

* Windows 10 Professional
* winget v0.1.41331 preview

**参考**

* [Windows Package Manager Preview] (https://devblogs.microsoft.com/commandline/windows-package-manager-preview/)
* [microsoft / winget-cli] (https://github.com/microsoft/winget-cli)

# インストール

インストールするには『[Windows Insider] (https://insider.windows.com/ja-jp/)』か『[Windows Package Manager Insider Program] (http://aka.ms/winget-InsiderProgram)』に参加して、Microsoftストアからインストールする方法と、GitHubの[microsoft / winget-cli] (https://github.com/microsoft/winget-cli)からソースコードをチェックアウトして自前でビルドする方法があります。
私の使用しているPCはWindows Insiderプログラムに参加しているので、Microsoftストアから『アプリ インストーラー』を更新する方法でインストールしました。

## アプリ インストーラーの更新

Microsoftストアにアクセスし（なお、MSA(マイクロソフトアカウント)でサインインしている必要があります）、検索フィールドに"app installer"と入力して検索します。
![Screenshot_4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22772/45e24f83-b008-30ca-01ca-6b6e032023dd.png)

検索結果に表示されている”アプリ インストーラー”が対象のアプリケーションです。
![Screenshot_5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22772/c2b9b706-2429-89fe-8c31-1ec772bcbc79.png)

インストールした覚えがないのに”インストール済み”と出ているかもしれませんが、これ自体は2016年頃から存在するアプリケーションで、Insiderプログラムに参加するとプレビュー版に更新されます。
（＊デフォルトでインストールされているアプリケーションらしく、アンインストールはできません）

この”アプリ インストーラー”をクリックすると図のようにプログラムの更新が行われます。
![Screenshot_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22772/54a0d50c-74aa-4751-d375-397360e885b2.png)

## winget

アプリ インストーラーが更新されるとパッケージマネージャ―クライアント（`winget`）が使用できるようになります。

```
> where winget
C:\Users\{USERNAME}\AppData\Local\Microsoft\WindowsApps\winget.exe
```

Powershellを起動しプロンプトから`winget`と入力して実行するとUsageが確認できます。

```powershell
❯ winget
Windows Package Manager v0.1.41331 プレビュー
Copyright (c) Microsoft Corporation. All rights reserved.

WinGet コマンド ライン ユーティリティを使用すると、コマンド ラインからアプリケーションをインストールできます。

usage: winget [<command>] [<options>]

使用できるコマンドは次のとおりです:
  install   指定されたアプリケーションをインストール
  show      アプリケーションに関する情報を表示
  source    アプリケーションのソースを管理
  search    アプリの基本情報を見つけて表示
  hash      インストーラー ファイルをハッシュするヘルパー
  validate  マニフェスト ファイルを検証

特定のコマンドの詳細については、それにヘルプ引数を渡します。 [-?]

次のオプションを使用できます。
  -v,--version  ツールのバージョンを表示
  --info        ツールの一般情報を表示

More help can be found at: https://aka.ms/winget-command-help
```

# wingetのコマンド

現時点(2020/05)で使用できるコマンドは

* install
* show
* source
* search
* hash
* validate

があります。
それぞれのコマンドの使い方は`-?` or `--help`オプションで確認できます。

```console:例
> winget install -?
```

## search コマンド

> アプリの基本情報を見つけて表示

```text:Usage
winget search [[-q] <query>] [<options>]
```

クエリやオプションを指定せずに実行すると、その時点で登録されているソース（リポジトリのこと）からインストールできるアプリケーションが確認できます。

```console
> winget search
```

※1画面分のスクリーンショットです。（これで全部ではありません）
![Screenshot_6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22772/f565fe9b-e4da-406d-0116-243b5972e0f1.png)

有名なものではAWS CLI、Git、Chrome、VSCode、Node.js、MySQL、Python、Ruby、Putty、Slackなどがありました。

### クエリ文字で検索

指定する文字列でアプリケーションを検索します。この例では"git"という文字列がメタデータのどこかしらに含まれているアプリケーションを検索します。

```console
> winget search -q git
```

`-q`オプションは省略可能なので以下のようにも書けます。`Matched`フィールドには、なぜヒットしたかの理由が出力されていることがあります。
たとえば2行目の`Sublime Merge`はNameにもIdにも"git"という文字列が含まれていませんが、Tagに"git"が登録されているためということがわかります。

```console
> winget search git
Name                                    Id                                       Version      Matched
----------------------------------------------------------------------------------------------------------
Git                                     Git.Git                                  2.26.2       Moniker: git
Sublime Merge                           SublimeHQ.SublimeMerge                   1119         Tag: git
Logitech Harmony Remote                 Logitech.Harmony                         1.0.1.308
GitHub Desktop                          GitHub.GitHubDesktop                     2.4.3
GitHub CLI                              GitHub.cli                               0.8.0
Atom                                    GitHub.Atom                              1.45.0
GitKraken                               Axosoft.GitKraken                        6.5.4
AdobeDigitalEditions                    Adobe.AdobeDigitalEditions               4.5.11
MicrosoftGitCredentialManagerforWindows Microsoft.GitCredentialManagerforWindows 1.20.0
Git Large File Storage                  GitHub.GitLFS                            2.11.0
Git Extensions                          GitExtensionsTeam.GitExtensions          3.3.1
MaxTo                                   DigitalCreations.MaxTo                   2.0.1
AppInstallerFileBuilder                 Microsoft.AppInstallerFileBuilder        1.2020.211.0 Tag: GitHub
```

検索する文字列に半角スペースがある場合はダブルクォーテーションで検索文字列を囲みます。

```console
❯ winget search "microsoft edge"
Name                Id                 Version
--------------------------------------------------
Microsoft Edge      Microsoft.Edge     83.0.478.37
Microsoft Edge Beta Microsoft.EdgeBeta 83.0.478.37
Microsoft Edge Dev  Microsoft.EdgeDev  84.0.516.1
```

### Nameで検索

`--name`オプションでNameフィールドに"git"という文字列が含まれているアプリケーションを検索します。
部分一致で検索するので1行目の`Logitech Harmony Remote`のようにGitと関係のないアプリケーションも検索されてしまいます。

```console
> winget search --name git
Name                                    Id                                       Version
------------------------------------------------------------------------------------------
Logitech Harmony Remote                 Logitech.Harmony                         1.0.1.308
GitHub Desktop                          GitHub.GitHubDesktop                     2.4.3
GitHub CLI                              GitHub.cli                               0.8.0
Git                                     Git.Git                                  2.26.2
GitKraken                               Axosoft.GitKraken                        6.5.4
AdobeDigitalEditions                    Adobe.AdobeDigitalEditions               4.5.11
MicrosoftGitCredentialManagerforWindows Microsoft.GitCredentialManagerforWindows 1.20.0
Git Large File Storage                  GitHub.GitLFS                            2.11.0
Git Extensions                          GitExtensionsTeam.GitExtensions          3.3.1
```

完全一致で検索するには`-e`オプションを指定します。ただし大文字小文字の区別も行われるようになるので、"git"だけだと下記のように逆に見つからなくなります。

```console
> winget search -e --name git
No app found matching input criteria.
```

名前で完全一致で検索するには大文字小文字を意識して、下記のように"Git"と検索することで目的のアプリケーションを検索することができます。

```console
> winget search -e --name Git
Name Id      Version
--------------------
Git  Git.Git 2.26.2
```

下記の例の`-e`オプションによる完全一致は、メタデータのどこかしらのフィールドが完全一致したアプリケーションがヒットします。
この例では`Matched`に出力されている通り、1行目が`Moniker`（通称）との完全一致、2行目が`Tag`との完全一致ということになります。

```
> winget search git -e
Name          Id                     Version Matched
---------------------------------------------------------
Git           Git.Git                2.26.2  Moniker: git
Sublime Merge SublimeHQ.SublimeMerge 1119    Tag: git
```

### Tagで検索

`--tag`オプションでTagフィールドに"editor"という文字列が含まれているアプリケーションを検索します。
使い方はNameで検索する方法と同じです。

```console
❯ winget search --tag editor
Name      Id                  Version  Matched
-------------------------------------------------------
Notepad++ Notepad++.Notepad++ 7.8.6    Tag: editor
GIMP      gimp.gimp           2.10.8   Tag: editor
Geany     Geany.Geany         1.36     Tag: editor
JabRef    JabRef.JabRef       5.0      Tag: editor
GIMP      GIMP.GIMP           2.10.18  Tag: editor
darktable darktable.darktable 3.0.2    Tag: editor
vim       vim.vim             8.2.0754 Tag: text editor
Atom      GitHub.Atom         1.45.0   Tag: texteditor
Bluefish  Bluefish.Bluefish   2.2.11   Tag: texteditor
GNU Emacs GNU.Emacs           27.0.91  Tag: text editor
```

## showコマンド

> アプリケーションに関する情報を表示

```text:Usage
winget show [[-q] <query>] [<options>]
```

検索条件に複数のアプリケーションがヒットした場合は、情報が表示されないので1件に絞り込むようにします。

```console
❯ winget show --name git
Multiple apps found matching input criteria. Please refine the input.
Name                                    Id                                       Version
------------------------------------------------------------------------------------------
Logitech Harmony Remote                 Logitech.Harmony                         1.0.1.308
GitHub Desktop                          GitHub.GitHubDesktop                     2.4.3
GitHub CLI                              GitHub.cli                               0.8.0
Git                                     Git.Git                                  2.26.2
GitKraken                               Axosoft.GitKraken                        6.5.4
AdobeDigitalEditions                    Adobe.AdobeDigitalEditions               4.5.11
MicrosoftGitCredentialManagerforWindows Microsoft.GitCredentialManagerforWindows 1.20.0
Git Large File Storage                  GitHub.GitLFS                            2.11.0
Git Extensions                          GitExtensionsTeam.GitExtensions          3.3.1
```

検索条件に一致するアプリケーションが1件に絞り込めた場合、下記のようにアプリケーションのマニフェストが表示されます。

```console
❯ winget show -e --name Git
Found Git [Git.Git]
Version: 2.26.2
Publisher: Git
Description: Git version control system.
Homepage: https://git-scm.com/
License: GNU General Public License, version 2
License Url: https://github.com/git-for-windows/git/blob/master/COPYING
Installer:
  SHA256: cdf76510979dace4d3f5368e2f55d4289c405e249399e7ed09049765489da6e8
  Download Url: https://github.com/git-for-windows/git/releases/download/v2.26.2.windows.1/Git-2.26.2-64-bit.exe
  Type: Inno
```

`--versions`オプションを加えると、インストール可能なバージョンの一覧が表示されます。

```console
❯ winget show -e --name Git --versions
Found Git [Git.Git]
Version
--------
2.26.2
2.25.1
2.24.1.2
```

`-v`オプションで指定するバージョンのアプリケーションのマニフェストが確認できます。

```console
❯ winget show -e --name Git -v 2.25.1
Found Git [Git.Git]
Version: 2.25.1
Publisher: Git
AppMoniker: git
Description: Git version control system.
Homepage: https://git-scm.com/
License: Copyright (C) 1991, 1999 Free Software Foundation, Inc. - GNU General Public License version 2.1
License Url: https://github.com/git/git/blob/master/LGPL-2.1
Installer:
  SHA256: 9e442131f7dc0de24db1369a4fe02659c2d642bf60ce6d88e31340eedaa18da1
  Download Url: https://github.com/git-for-windows/git/releases/download/v2.25.1.windows.1/Git-2.25.1-64-bit.exe
  Type: Inno
```

### winget-pkgs

> The Microsoft community Windows Package Manager manifest repository

GitHubに[microsoft / winget-pkgs](https://github.com/microsoft/winget-pkgs) というMicrosoftコミュニティのマニフェストリポジトリがあります。

上記のshowコマンドで表示したマニフェストはこのリポジトリで管理されているようです。たとえばVersion 2.26.2のGitのマニフェストは`2.26.2.yaml`というファイルで

https://github.com/microsoft/winget-pkgs/blob/master/manifests/Git/Git/2.26.2.yaml

```yaml
Id: Git.Git
Name: Git
Version: 2.26.2
Publisher: Git
Homepage: https://git-scm.com/
License: GNU General Public License, version 2
LicenseUrl: https://github.com/git-for-windows/git/blob/master/COPYING
Description: Git version control system.
InstallerType: Inno
Installers:
  - Arch: x64
    Url: https://github.com/git-for-windows/git/releases/download/v2.26.2.windows.1/Git-2.26.2-64-bit.exe
    Sha256: cdf76510979dace4d3f5368e2f55d4289c405e249399e7ed09049765489da6e8
```

のようになっています。（内容は2020/05時点のもの）

## sourceコマンド

> アプリケーションのソースを管理

ソースというのはアプリケーションのリポジトリのことです。

```text:Usage
winget source <command>
```

### サブコマンド

sourceコマンドには、以下のサブコマンドがあります。

* add    : 新しいソースを追加
* list   : 現在のソースを一覧表示
* update : 現在のソースを更新
* remove : 現在のソースを削除
* reset  : ソースをリセット

### list サブコマンド

現時点(2020/05)で登録されているソースは1つ(`winget`)だけでした。

```console
❯ winget source list
Name   Arg
-----------------------------------------
winget https://winget.azureedge.net/cache
```

`-n` or `--name`オプションでソース名を指定すると、そのソースの情報を確認できます。

```console
❯ winget source list -n winget
Name   : winget
Type   : Microsoft.PreIndexed.Package
Arg    : https://winget.azureedge.net/cache
Data   : Microsoft.Winget.Source_2020.520.851.931_neutral__8wekyb3d8bbwe
Updated: 2020-5-21 08:31:51.000
```

* Name : ソースを識別するための名前を表示します。
* Type : リポジトリのタイプを表示します。
* Arg : ソースが使用するURLまたはパスを表示します。
* Data : 必要に応じて使用されるオプションのパッケージ名を表示します。
* Updated : ソースが更新された最終日時を表示します。

### show, search, installコマンドでソースを指定する

show、search、installコマンドには`-s` or `--source`オプションがありソース名を指定してコマンドの実行範囲を限定することができます。

下記は`winget`ソースから"power"という文字列でアプリケーションを検索する例です。

```console:例
❯ winget search -s winget power
Name             Id                         Version        Matched
----------------------------------------------------------------------------
PowerToys        Microsoft.PowerToys        0.18.0
Powershell       Microsoft.Powershell       7.0.1
PowerBI Desktop  Microsoft.PowerBI          2.81.5831.621
ConfigMgrToolkit Microsoft.ConfigMgrToolkit 5.00.7958.1151 Tag: Power Viewer
```

## installコマンド

> 指定されたアプリケーションをインストール

```text:Usage
> winget install [[-q] <query>] [<options>]
```

### Notepad++をインストール

試しにNotepad++をインストールしてみます。

```console
❯ winget install notepad
Found Notepad++ [Notepad++.Notepad++]
This application is licensed to you by its owner.
Microsoft is not responsible for, nor does it grant any licenses to, third-party packages.
Downloading https://github.com/notepad-plus-plus/notepad-plus-plus/releases/download/v7.8.6/npp.7.8.6.Installer.x64.exe
  ██████████████████████████████  3.85 MB / 3.85 MB
Successfully verified installer hash
Installing ...
Successfully installed!
```

途中で管理者権限への昇格が求められましたがインストールが成功すると、従来のインストール方法（アプリケーションのインストーラーなど）でインストールしたのと同様に、スタートメニューに追加されたり、アプリと機能に表示されます。

**スタートメニュー**
![Screenshot_7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22772/fde55ddb-b618-f05c-0021-ffcf733f191e.png)

**アプリと機能**
![Screenshot_8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22772/885a5cb5-27a5-7192-2c90-fa1aa2321d1f.png)

現時点(2020/05)では、winget経由でインストールしたアプリケーションの確認やアンインストールはできないようです。（それらしいオプションが無いので）

アンインストールについては、アプリと機能で別途アンインストールすることになるのではないかと思います。

**どこにインストールされたか**

デフォルトでは`C:\Program Files\Notepad++`にインストールされていました。
![Screenshot_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22772/08792831-5d8a-73fb-a5d9-7bac8b339190.png)

#### インストール先を指定する

installコマンドには`-l` or `--location`というインストール先を指定できるオプションがあります。（ただし、オプションの説明に"インストール先 (サポートされている場合)"とある通り、必ずしも反映されるわけではないようです。）

Notepad++をアンインストールして、もう一度`-l`オプションを指定してインストールしてみます。
`C:\dev`をインストール先に指定しましたが、そこにはインストールされず`C:\Program Files\Notepad++`にインストールされました。

```console
❯ winget install --name notepad -l "C:\dev"
```

#### インストールログを出力する

`-o` or `--log`オプションでインストールログの出力先を指定できるようですが、試したことろ指定した場所にログは出力できませんでした。

```console
❯ winget install --name notepad -o "c:\dev\install.log"
```

# まとめ

最初のプレビュー版がリリースされたばかりですが、すでにいくつかの有名なアプリケーションがソース（リポジトリ）に登録されていました。

これまではWindows PCにアプリケーションをインストールするには、アプリケーション固有のインストーラーを使うか、[Chocolatey] (https://chocolatey.org/)や[Scoop] (https://scoop.sh/)などを利用する方法がありましたが、Windows Package Managerが標準になってインストール方法が統一されると便利になるのではないかと思います。

hashとvalidateコマンドについては、どのように使うコマンドなのか調べ切れなかったので触れませんでしたが、この辺りを含めてもう少し詳しく調べるのはバージョンが上がってからにしようと思います。