Windowsの環境変数設定を自動化してみた

## はじめに
 ツールやライブラリの実行ファイルが格納された `bin` フォルダを環境変数 `Path` に追加する作業を自動化できないかと思い、**`bin` フォルダを自動で探索し、環境変数 `Path` に追加するバッチスクリプト**を作成してみました。 

## スクリプトの概要

今回作成したスクリプトは以下の3つ

1. **`AddUserPath.bat`**  
   <details><summary>ソースコード</summary>
   
    ```bat
    @echo off

    :: バックアップスクリプトのファイル名を変数で管理
    set BACKUP_SCRIPT=BackupUserPath.bat

    :: バックアップを実行するか確認
    echo この処理を行う前に、現在のユーザー環境変数 Path をバックアップすることを推奨します。
    set /p BACKUP_CHOICE="バックアップを実行しますか？ (Y/N): "

    if /i "%BACKUP_CHOICE%"=="Y" (
        if exist "%~dp0%BACKUP_SCRIPT%" (
            echo %BACKUP_SCRIPT% を実行しています...
            call "%~dp0%BACKUP_SCRIPT%"
        ) else (
            echo エラー: %BACKUP_SCRIPT% が見つかりません。スクリプトを中止します。
            pause
            exit /b 1
        )
    ) else (
        echo バックアップをスキップしました。
    )

    :: 現在のユーザー環境変数 Path を取得
    for /f "tokens=2*" %%A in ('reg query "HKCU\Environment" /v Path 2^>nul') do (
        set CURRENT_PATH=%%B
    ) || (
        echo エラー: 現在の Path を取得できませんでした。
        pause
        exit /b 1
    )

    :: 新しい Path 値を一時的に格納する変数
    set NEW_PATH=%CURRENT_PATH%
    
    :: bin フォルダを再帰的に検索して追加
    for /r "%~dp0" %%D in (.) do (
        if /i "%%~nD"=="bin" (
            call :add_to_path "%%~fD"
        )
    )

    :: Path の長さ制限を確認
    if not "%NEW_PATH:~2047%"=="" (
        echo エラー: Path の長さが制限を超えています。
        pause
        exit /b 1
    )
    
    :: ユーザー環境変数 Path を更新
    reg add "HKCU\Environment" /v Path /t REG_EXPAND_SZ /d "%NEW_PATH%" /f >nul 2>&1
    if errorlevel 1 (
        echo エラー: Path の更新に失敗しました。
        pause
        exit /b 1
    )
    
    :: 完了メッセージ
    echo 環境変数 Path を更新しました。
    echo 新しい Path: %NEW_PATH%
    pause
    exit /b
    
    :add_to_path
    :: %1: bin フォルダのフルパス
    set "NEW_ENTRY=%~1"
    
    :: パスが既存の Path に含まれているか確認
    echo %CURRENT_PATH% | find /i "%NEW_ENTRY%" >nul
    if not errorlevel 1 (
        echo 既に登録済み: %NEW_ENTRY%
        goto :eof
    )
    
    :: 新しいパスを Path に追加
    echo 追加: %NEW_ENTRY%
    set NEW_PATH=%NEW_PATH%;%NEW_ENTRY%
    goto :eof
    ```

</details>



2. **`BackupUserPath.bat`**  
   <details><summary>ソースコード</summary>

   ```bat
    @echo off
    :: ユーザー環境変数をバックアップするスクリプト
    set BACKUP_FILE=UserPathBackup.txt
    
    :: ユーザー環境変数 Path の値をレジストリから取得
    for /f "tokens=2*" %%A in ('reg query "HKCU\Environment" /v Path 2^>nul') do (
        echo %%B > "%~dp0%BACKUP_FILE%"
    ) || (
        echo エラー: 現在の Path を取得できませんでした。
        pause
        exit /b 1
    )
    
    :: バックアップ完了メッセージ
    if exist "%~dp0%BACKUP_FILE%" (
        echo ユーザー環境変数 Path をバックアップしました:
        echo %~dp0%BACKUP_FILE%
    ) else (
        echo エラー: バックアップファイルの作成に失敗しました。
    )
    
    pause
   ```

</details>


3. **`RestoreUserPath.bat`**  
   <details><summary>ソースコード</summary>

    ```bat
    @echo off
    :: バックアップファイルの名前を設定
    set BACKUP_FILE=UserPathBackup.txt
    
    :: バックアップファイルが存在するか確認
    if not exist "%~dp0%BACKUP_FILE%" (
        echo エラー: バックアップファイル "%BACKUP_FILE%" が見つかりません。
        pause
        exit /b 1
    )
    
    :: バックアップファイルから Path 値を読み込む
    set /p RESTORED_PATH=<"%~dp0%BACKUP_FILE%"
    if "%RESTORED_PATH%"=="" (
        echo エラー: バックアップファイルが空です。
        pause
        exit /b 1
    )
    
    :: 確認メッセージを表示
    echo 次のユーザー環境変数 Path をリストアします:
    echo %RESTORED_PATH%
    set /p CONFIRM="復元を実行しますか？ (Y/N): " 
    
    if /i not "%CONFIRM%"=="Y" (
        echo 復元をキャンセルしました。
        pause
        exit /b 0
    )
    
    :: Path を復元
    reg add "HKCU\Environment" /v Path /t REG_EXPAND_SZ /d "%RESTORED_PATH%" /f
    if errorlevel 1 (
        echo エラー: Path の復元に失敗しました。
        pause
        exit /b 1
    )
    
    :: 完了メッセージ
    echo ユーザー環境変数 Path を復元しました。
    pause
    ```
</details>


## スクリプトの使い方

### 1. スクリプトを配置

上記の3つのスクリプトを、`C:\Users\ユーザ名\tools` などの適当なフォルダに配置。  


### 2. 実行手順

1. **`AddUserPath.bat` を実行**  
   AddUserPath.bat を実行すると、以下の処理が行われる：
   - バックアップ実行を選択した場合はバックアップファイルを生成
   - スクリプトが配置されたフォルダを再帰的に探索し、`bin` フォルダを見つける
   - 見つけた `bin` フォルダを `Path` に追加
   - 既に登録済みのフォルダはスキップ
　　

2. **復元が必要な場合**  
   `RestoreUserPath.bat` を実行して `Path` を復元
　　
3. **バックアップのみを行う場合**
 `BackupUserPath.bat`を実行してバックアップファイルを生成


## 実行例

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3485511/ef49e0dc-340e-402e-a76e-67a386539048.png)

```
この処理を行う前に、現在のユーザー環境変数 Path をバックアップすることを推奨します。
バックアップを実行しますか？ (Y/N): y
BackupUserPath.bat を実行しています...
ユーザー環境変数 Path をバックアップしました:
C:\Users\Tomoki\tools\UserPathBackup.txt
続行するには何かキーを押してください . . .
既に登録済み: C:\Users\Tomoki\tools\ffmpeg-7.1.1-essentials_build\bin
追加: C:\Users\Tomoki\tools\mingw64\bin
追加: C:\Users\Tomoki\tools\mingw64\opt\bin
追加: C:\Users\Tomoki\tools\mingw64\x86_64-w64-mingw32\bin
環境変数 Path を更新しました。
新しい Path: C:\Users\Tomoki\AppData\Local\Programs\Python\Python312\Scripts\;C:\Users\Tomoki\AppData\Local\Programs\Python\Python312\;C:\Users\Tomoki\AppData\Local\Microsoft\WindowsApps;C:\Users\Tomoki\AppData\Roaming\Programs\Zero Install;C:\Users\Tomoki\AppData\Local\Programs\Microsoft VS Code\bin;C:\Users\Tomoki\tools\ffmpeg-7.1.1-essentials_build\bin;;C:\Users\Tomoki\tools\mingw64\bin;C:\Users\Tomoki\tools\mingw64\opt\bin;C:\Users\Tomoki\tools\mingw64\x86_64-w64-mingw32\bin
続行するには何かキーを押してください . . .
```

## まとめ
そもそも環境変数にパスを通す機会が少ないってのは言わないお約束