📦

あなたのWindows環境、WingetとScoopで自動化しませんか?

はじめに

体に悪いものをキメているみなさん、ごきげんよう。
電通大2年生、team411のメイドさん③のむつみんです。

昨日の記事は、akaakuさんによるココパズルのすべてでした!
まさか作ったものがあの試験に出題されてしまうとは……
ものすごい偶然ですが一度は体験してみたいものですね。

さて皆さん、Windows環境のセットアップに苦労していませんか?
新しいPCを買ったときや、OSを再インストールしたときに、必要なソフトウェアを一つ一つ手動でインストールするのは非常に面倒です。

そんな時に役に立つのがパッケージマネージャーです。
パッケージマネージャーとは、ソフトウェアのインストール、アップデート、アンインストールを一元管理するシステムやツールのことです。
これを使うことでわざわざ公式サイトからzipファイルやインストーラーをダウンロードしてインストールする手間が省け、コマンド一つで必要なソフトウェアをまとめてインストールできるようになります。

今回はWingetとScoopという2つのパッケージマネージャーを使って、Windows環境のセットアップを自動化する方法を紹介します。

皆さんの中には既にWingetでソフトウェアをインストールしている方もいるかもしれませんが、Wingetはまだまだ発展途上であり、すべてのソフトウェアが対応しているわけではありません。
また、バージョン管理やカスタムリポジトリの利用など、より高度な機能が必要な場合もあります。
そこで、Windowsで広く使われているもう一つのパッケージマネージャーであるScoopも併用することで、より多くのソフトウェアを簡単にインストールできるようになります。

2つ併用するというのは少し気持ち悪いかもしれませんが、実際にはそれぞれの強みを活かして使い分けることで非常に効率よくWindows環境を整備することができます。

それでは実際に、WingetとScoopを使ってWindows環境を整備する方法を見ていきましょう。

対象読者

  • Windowsユーザーで、環境構築を自動化したい方
  • WingetやScoopに興味がある方
  • DotFiles管理に興味がある方

非対象読者

  • 手動での環境構築に満足している方
  • Mac信者の方
  • Linux信者の方
  • Windowsアンチの方(私)

え、なんでWindows使ってるのかって?
それはね、お金がなくて惰性で使ってるからです……
早くMacに乗り換えて古いPCはLinuxにしたいけど、今は時期が悪いおじさんが今は時期が悪いと言っているので仕方ないですね。

この記事で得られること

  • WingetとScoopの基本的な使い方
  • WingetとScoopを併用したWindows環境の整備方法
  • DotFiles管理の基本的な考え方

この記事で扱わないこと

  • DotFilesの詳細な管理方法
  • Chocolateyなど、他のパッケージマネージャーの紹介
  • Mac、Linuxでの環境構築方法

WingetとScoopの概要

Wingetとは?

Wingetは、魔のMicrosoftが提供するWindows用のパッケージマネージャーです。
Wingetを使うことで、一般的なパッケージマネージャーと同様にコマンドラインからソフトウェアのインストール、アップデート、アンインストール、環境変数の設定などが簡単に行えます。

WingetはWindows 10 バージョン1809以降とWindows 11に標準で搭載されており、Microsoft StoreからもApp Installerという形でインストールできます。
Wingetの主な特徴は以下の通りです。

  • 公式サポート: Microsoftが提供しているためWindowsとの互換性が高く、またセットアップの手間が少ない。
  • シンプルなコマンド: 直感的なコマンドで操作が可能。
  • 安全性: Microsoftの審査を通過したパッケージが提供されるため、セキュリティ面で安心。
  • パッケージの広いサポート: 一般的なソフトウェアはもちろん、GUIアプリケーション、CLIツール、ライブラリなど幅広いパッケージが利用可能。
    Microsoft Storeに登録されているアプリケーションもインストール可能であり、Windows内に既にインストールされているアプリケーションの管理もできる。

Scoopとは?

Scoopは、Windows用のもう一つのパッケージマネージャーで、主に開発者向けのツールやユーティリティを簡単にインストールできるように設計されています。
ScoopはPowerShellをベースにしており、コマンドラインからソフトウェアのインストール、アップデート、アンインストールが可能です。
Scoopの主な特徴は以下の通りです。

  • シンプルなインストール: PowerShellを使って簡単にインストールでき、セットアップが非常に簡単。さらにパスの設定もしないため環境が汚れない。
  • ポータブル指向: ユーザーのホームディレクトリにソフトウェアをインストールするため管理者権限が不要であり、システムへの影響が少ない。
    そのため、個人でパソコンを切り替えて使う場合に便利。
  • 多様なパッケージ: 開発者向けのツールやユーティリティが豊富に揃っており、特にCLIツールのインストールに強みを持つ。
  • カスタムリポジトリ: ユーザーが独自のバケット(リポジトリ)を作成・共有できるため、特定のニーズに合わせたパッケージ管理が可能。
  • クリーンなアンインストール: アンインストール時にWindowsの「プログラムの追加と削除」を経由しないため、PC上に不要なゴミが残らない。

WingetとScoopの違い

WingetとScoopはどちらもWindows用のパッケージマネージャーですが、いくつかの違いがあるので、以下の表に簡単にまとめてみました。

特徴 Winget Scoop
提供元 Microsoft オープンソースコミュニティ
インストール場所 システム全体(管理者権限が必要) ユーザープロファイル(管理者権限不要)
アンインストール方法 コマンドで簡単に削除可能だがWindowsのアンインストール機能を使用 直接アンインストール
パッケージの種類 GUIアプリケーション、CLIツール、ライブラリなど幅広い 主にCLIツールや開発者向けツールに特化
セキュリティ Microsoftの審査を通過したパッケージが提供される なし
環境への影響 PATH環境変数やインストール済みのアプリの登録がされる PATH環境変数の変更なし

これだけ見ると、WingetとScoopはそれぞれ異なる強みを持っていることがわかります。

Wingetは公式サポートがあり、システム全体に影響を与えるため、GUIなどをもつ一般的なソフトウェアのインストールに適しています。
しかしインストールしたツールごとにPATH環境変数が追加されてしまうため、環境が汚れやすいという欠点もあります。

それに対してScoopはポータブル指向であり、CLIツールや開発者向けのツールのインストールに強みを持っています。
インストール場所がユーザープロファイル内であるため管理者権限が不要ですし、何より環境が汚れないのが大きなメリットです。
そのため、.exeのみを使う一般的なツールなんかはScoopでインストールする方が使い勝手が良いとされています。[1]

Windowsにおいては環境が汚れると後々のトラブルの元になることが多いため、Scoopのようにユーザーに対してインストールする方式は非常に魅力的でよね。
ただScoopだとVS CodeのようなGUIアプリをインストールするときにシステムにインストールしないことによる不具合が起きることもあるため、両者をうまく使い分けることができれば非常にうれしいです。

そんな訳だからWingetとScoopを併用した環境を作ってしまおう!
というのが今回の記事の趣旨になります。

WingetとScoopのインストール

Wingetのインストール

先程述べた通り、WingetはWindows 10 バージョン1809以降とWindows 11に標準で搭載されています。
なのでインストールが必要になるのはそれ以前のバージョンのWindowsを使っている場合のみです。

もしWingetがインストールされていない場合は、以下の手順でインストールできます。

  1. App Installerのインストール:

    • Microsoft Storeを開き、検索バーに「App Installer」と入力します。
    • 検索結果から「App Installer」を選択し、「入手」ボタンをクリックしてインストールします。
  2. Wingetの確認:

    • インストールが完了したら、コマンドプロンプトまたはPowerShellを開き、以下のコマンドを実行してWingetが正しくインストールされているか確認します。
    winget --version
    

バージョン情報が表示されれば、Wingetのインストールは成功です。

実際にWingetでは、

winget search <キーワード>
winget install <アプリ名>
winget upgrade <アプリ名>
winget upgrade --all
winget list
winget uninstall <アプリ名>

といったコマンドで好きなソフトウェアを管理できます

Scoopのインストール

Scoopのインストールは非常に簡単で、PowerShellを使って以下のコマンドを実行するだけです。

Set-ExecutionPolicy RemoteSigned -Scope CurrentUser
iwr -useb get.scoop.sh | iex

このコマンドは、PowerShellの実行ポリシーを変更し、Scoopのインストールスクリプトをダウンロードして実行するものです。

インストールが完了したら、以下のコマンドを実行してScoopが正しくインストールされているか確認します。

scoop --version

バージョン情報が表示されれば、Scoopのインストールは成功です。

Scoopを使うときは少し注意が必要で、Scoopはバケットというリポジトリのようなものを追加しないとインストールできないソフトウェアも多いです。

scoop bucket add extras

これで様々なソフトウェアもインストール可能になり、

scoop search <キーワード>
scoop install <アプリ名>
scoop update <アプリ名>
scoop update *  # 全アプリ更新
scoop list  # インストール済みアプリ一覧
scoop uninstall <アプリ名>

といったコマンドで好きなソフトウェアを管理できます。

WingetとScoopを使ったソフトウェアのインストール

セットアップスクリプトを組んでみた

ただWingetとScoopでもインストールするソフトウェアを一つ一つ手動で指定するのは面倒ですよね。
特に新しいWindows環境に移行したり、Windowsを初期化したときに毎回同じソフトウェアをインストールするのは非常に手間がかかります。

そこで、WingetとScoopを使って必要なソフトウェアを自動的にインストールするセットアップスクリプトをこんな感じで作成してみました。

# Dotfiles Setup Script for Windows
# Combines Scoop (CLI) and Winget (GUI)

$ErrorActionPreference = "Stop"


function Install-Scoop {
    Write-Host "`n[1/4] Setting up Scoop..." -ForegroundColor Cyan
    if (-not (Get-Command scoop -ErrorAction SilentlyContinue)) {
        Write-Host "Installing Scoop..."
        # Check if running as administrator
        $currentPrincipal = New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())
        if ($currentPrincipal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
            Write-Host "Running as administrator. Attempting all-user Scoop installation."
            # For all-user installation of Scoop when running as admin
            # Temporarily set ExecutionPolicy for LocalMachine
            $originalExecutionPolicy = Get-ExecutionPolicy -Scope LocalMachine
            Set-ExecutionPolicy RemoteSigned -Scope LocalMachine -Force

            Invoke-RestMethod -Uri https://get.scoop.sh | Invoke-Expression

            # Restore original ExecutionPolicy for LocalMachine
            Set-ExecutionPolicy $originalExecutionPolicy -Scope LocalMachine -Force

            # Complete all-user Scoop installation
            scoop install scoop
        } else {
            Write-Host "Running as regular user. Attempting current-user Scoop installation."
            # For current-user installation of Scoop when running as regular user
            Set-ExecutionPolicy RemoteSigned -Scope CurrentUser -Force
            Invoke-RestMethod -Uri https://get.scoop.sh | Invoke-Expression
        }
    } else {
        Write-Host "Scoop is already installed."
    }

    Write-Host "Adding Scoop buckets..."
    scoop bucket add extras  # For GUI apps
    scoop bucket add versions  # For alternative versions
    scoop bucket add nerd-fonts  # For fonts like Hack-NF
}

function Install-CLI-Tools {
    Write-Host "`n[2/4] Installing CLI tools via Scoop..." -ForegroundColor Cyan
    # If you want to add more apps, just add them to this array
    $apps = @(
        "neovim",
        "gcc",        # Needed for nvim-treesitter
        "ripgrep",    # Needed for Telescope/fzf
        "fd",         # Needed for Telescope/fzf
        "lazygit",    # Git UI
        "starship",   # Prompt
        "fzf",
        "eza",        # ls replacement
        "bat",        # cat replacement
        "delta",      # git diff viewer
        "zoxide"      # cd replacement
    )

    foreach ($app in $apps) {
        if (-not (Get-Command $app -ErrorAction SilentlyContinue)) {
            Write-Host "Installing $app..."
            scoop install $app
        } else {
            Write-Host "$app is already installed."
        }
    }
}

function Install-GUI-Apps {
    Write-Host "`n[3/4] Installing GUI apps via Winget..." -ForegroundColor Cyan

    $apps = @(
        "Git.Git",                    # Git
        "wez.wezterm",                # WezTerm
        "Microsoft.VisualStudioCode", # Visual Studio Code
        "Unity.UnityHub",             # Unity Hub
        "TigerVNC.TigerVNC",          # TigerVNC
        "Discord.Discord",            # Discord
        "Brave.Brave"                 # Brave Browser
    )

    foreach ($id in $apps) {
        Write-Host "Installing $id..."
        # winget handles "already installed" checks, though it might check for updates
        winget install --id $id -e --source winget --accept-source-agreements --accept-package-agreements
    }

    # Font (Moralerspace Neon is recommended in your config, but trying a generic Nerd Font via Scoop is safer for automation)
    # If you want Moralerspace specifically, you might need to download it manually or find a specific scoop bucket.
    # Installing a fallback font just in case:
    # scoop install Hack-NF
}

function Setup-Symlinks {
    Write-Host "`n[4/4] Linking Dotfiles..." -ForegroundColor Cyan

    $dotfiles = $PSScriptRoot
    $config   = "$env:USERPROFILE\.config"

    if (-not (Test-Path $config)) { New-Item -ItemType Directory -Path $config | Out-Null }

    # Helper function to create symlink
    function Link-File {
        param($Src, $Dest)
        if (Test-Path $Dest) {
            Write-Host "  Skipping $Dest (already exists)" -ForegroundColor DarkGray
        } else {
            Write-Host "  Linking $Dest -> $Src"
            New-Item -ItemType SymbolicLink -Path $Dest -Value $Src | Out-Null
        }
    }

    # 1. Neovim
    Link-File -Src "$dotfiles\nvim" -Dest "$env:LOCALAPPDATA\nvim"

    # 2. WezTerm (Using XDG standard path)
    Link-File -Src "$dotfiles\wezterm" -Dest "$config\wezterm"

    # 3. Starship
    Link-File -Src "$dotfiles\starship.toml" -Dest "$config\starship.toml"

    # 4. PowerShell Profile
    # $PROFILE is usually Documents\PowerShell\Microsoft.PowerShell_profile.ps1
    $psDir = Split-Path $PROFILE
    if (-not (Test-Path $psDir)) { New-Item -ItemType Directory -Path $psDir | Out-Null }

    # Instead of replacing the profile, we source our dotfiles profile
    # Using format operator -f to avoid escaping issues
    $profilePath = "$dotfiles\powershell\profile.ps1"
    $loadCmd = '. "{0}"' -f $profilePath

    if (Test-Path $PROFILE) {
        $content = Get-Content $PROFILE -Raw
        if ($content -notmatch "DotFiles\\powershell\\profile.ps1") {
            Write-Host "  Appending to existing PowerShell profile..."
            Add-Content -Path $PROFILE -Value "`n$loadCmd"
        } else {
            Write-Host "  PowerShell profile already configured." -ForegroundColor DarkGray
        }
    } else {
        Write-Host "  Creating PowerShell profile..."
        Set-Content -Path $PROFILE -Value $loadCmd
    }
}

# --- Main Execution ---

Install-Scoop
Install-CLI-Tools
Install-GUI-Apps
Setup-Symlinks

Write-Host "`nSetup Complete! Please restart your terminal." -ForegroundColor Green

おお、クソでか……

私が以前書いてたスクリプトを書き換えるのにGemini-CLIと殴り合った結果こんな感じになりました。

ただやっていることは単純で、スクリプトは以下の4つのステップで構成されています。

  1. Scoopのセットアップ: Scoopがインストールされていない場合はインストールし、必要なバケット(extras, versions, nerd-fonts)を追加します。
  2. CLIツールのインストール: Scoopを使ってNeovim、GCC、Ripgrep、fd、Lazygit、Starship、fzf、eza、bat、delta、zoxideなどのCLIツールをインストールします。
  3. GUIアプリのインストール: Wingetを使ってGit、WezTerm、Visual Studio Code、Unity Hub、TigerVNC、Discord、Brave BrowserなどのGUIアプリをインストールします。Wingetを使ってGitをインストールしてるのは、他のプログラムでProgram FilesにインストールされているGitを参照してしまう問題を避けるためです。[1:1]
  4. DotFilesのシンボリックリンク設定: DotFilesディレクトリからNeovim、WezTerm、Starship、PowerShellプロファイルの設定ファイルを適切な場所にシンボリックリンクとして配置します。

このスクリプトを実行することで、新しいWindows環境に必要なソフトウェアが自動的にインストールされ、設定していればになりますが、DotFilesの設定も適用されます。
既にツールがインストールされている場合はスキップするようになっているので、何度実行しても大丈夫です。
というかこのチェックを入れるためにかなりコードが冗長になってしまいました……

また、もしScoopやWingetでインストールしたいアプリがあれば$apps配列に追加するだけで簡単に拡張できるようになっているので、自分なりにカスタマイズ可能です。

今回は参考としてScoop側ではgitやGCCなどの基本的なツールに加えて、インストールすると既存の環境が便利になるCLIツールを中心に選びました。
ちょっと紹介すると、大体以下のような感じです。

  • neovim: 高機能なテキストエディタ。マウス操作をしなくて良いのがとても楽
  • ripgrep: Rust言語による高速な検索ツール。従来のgrepを強化してくれる
  • fd: 高速なファイル検索ツール。findコマンドの代替
  • lazygit: Gitの操作を簡単にするTUIツール
  • starship: 高速でカスタマイズ可能、どの環境でも使えるシェルプロンプト
  • fzf: コマンドラインでファイルを曖昧検索できる優れもの
  • eza: lsコマンドの代替ツール。カラフルな表示が可能
  • bat: catコマンドの代替ツール。シンタックスハイライトが可能
  • delta: git diffコマンドの代替ツール。差分表示が見やすくなる
  • zoxide: cdコマンドの代替ツール。頻繁にアクセスするディレクトリへの移動が高速化される。

入れると世界が変わるのでぜひ試してみてください。

スクリプトの実行方法

スクリプトを実行するときは、次の通りにしてください。

  1. PowerShellを開く
  2. git cloneなどでリポジトリをクローンする
git clone https://github.com/sasori-256/DotFiles

もしgitがない場合は先にwinget install Git.Gitなどでインストールしてください。

もしくはこのセットアップスクリプトをコピーしてテキストファイルに貼り付け、setup-windows.ps1などの名前で保存しても構いません。

  1. DotFilesディレクトリに移動する
  2. 以下のコマンドを実行してスクリプトを実行する
.\setup-windows.ps1
  1. スクリプトが完了したら、PowerShellを再起動する。

DotFilesの管理

DotFilesについて補足ですが、DotFilesとは、ユーザーの設定ファイルや構成ファイルを指します。
これらは通常、Windowsなら~\AppData\local\や~.configなど、MacやLinuxなら./.configなど、ホームディレクトリに隠しファイルとして保存されます。
内容としては、シェルの設定ファイル、エディタの設定ファイル、ターミナルの設定ファイルだったりが含まれます。

ただこれらの設定をパソコンごとに手動で行うのは非常に面倒ですよね。
私は複数のパソコンでNeovimを使いまわしたかったので面倒でした。

そこでこれらDotFilesをリポジトリで一元管理し、セットアップもスクリプトで自動化することで、環境構築の手間を大幅に削減できます。

StarshipやWeztermなどのDotFilesの詳細な設定については今回は触れませんが、内容は以下のリポジトリで公開していますので参考にしてください。

一応FishやHyprLandなど、まだArchLinuxの方で使ってる設定を反映しきれていないので、今後改善していく予定です。

おわりに

今回はWingetとScoopを使ってWindows環境のセットアップを自動化する方法を紹介しました。
WingetとScoopを併用することで、GUIアプリケーションとCLIツールの両方を効率よくインストールできるようになります。
また、DotFilesを使って設定ファイルを管理することで、環境の再現性も向上します。
ぜひ皆さんもWingetとScoopを活用して、快適なWindows環境を手に入れてください。

ただまぁWingetが成熟してもっと便利になれば一本化できたりするのですが……
今後に期待ですね。

え、他のOSだと一本化できてるって?
うっ

明日のAdvent Calendarは、我らがみみちゃん(team411のメイドさん①)による=>nilです!
とっても楽しそうですの!

脚注
  1. Windows向けパッケージマネージャーの比較 ↩︎ ↩︎

Discussion