LoginSignup
14
10

More than 3 years have passed since last update.

Chocolateyでのインストール直後にPATH変更を反映する

Last updated at Posted at 2019-01-19

やりたいこと

  • Windows コマンドスクリプト(.cmd)や PowerShell(.ps1) で環境構築を自動化すべく、chocolatey で git や python をインストールし、続けて git や python を使って環境構築を完結させる。

「スクリプトなんだから続けて書けばいいだけじゃん。」と思うが、そこには落とし穴が。

課題・落とし穴

次の手順をスクリプトとして実装すれば git を使ってリポジトリのクローンまでできそうに思える。

  1. chocolatey をインストール
  2. choco install で git をインストール
  3. インストールされた git コマンドでリポジトリをクローン

しかし、これを試すと、2. で git のインストールが成功しても、3. の git コマンド実行時に次のエラーが出て、期待通りに動かない。

'git' は、内部コマンドまたは外部コマンド、
操作可能なプログラムまたはバッチ ファイルとして認識されていません。

実は、choco install で git をインストール時のログをよく見てみると、次のようなメッセージが出力されている。

Environment Vars (like PATH) have changed. Close/reopen your shell to
 see the changes (or in powershell/cmd.exe just type `refreshenv`).
 The install of git.install was successful.
  Software installed to 'C:\Program Files\Git\'

要約すると次の通り。

PATH などの環境変数の変更を反映するには、シェルを開きなおすか、refreshenv を使う必要がある。

例えば、git の場合は、PATH 設定に C:\Program Files\Git\cmd が追加されるが、レジストリは更新されていても、現在実行中のシェルの PATH は更新されていない。

対応方法

  • choco install でパッケージをインストールした後、refreshenv を実行する。

    この refreshenv は Chocolatery に付属のヘルパースクリプト。実体は Windows コマンドの場合は RefreshEnv.cmd、Powershell の場合は Update-SessionEnvironment 関数のエイリアス。

  • Windows コマンドの場合の例

choco install -y git python
call refreshenv

git --version
python --version
  • PowerShell の場合は、次の記事の通り、ヘルパーモジュールをインポートしておく必要もある。

How to refresh the environment of a PowerShell session after a Chocolatey install without needing to open a new session - Stack Overflow

$env:ChocolateyInstall = Convert-Path "$((Get-Command choco).path)\..\.."
Import-Module "$env:ChocolateyInstall\helpers\chocolateyProfile.psm1"

choco install -y git python
refreshenv

git --version
python --version

参考情報

レジストリ中の PATH 設定を取得する方法

Windows コマンドの場合

  • 次のレジストリーを取得する。
    • "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" -> "Path"
    • "HKEY_CURRENT_USER\Environment" -> "Path"
  • ただし、%SystemRoot% のような環境変数が埋め込まれている場合があり、そのまま PATH に設定すると正常に動作しなくなる場合がある。
@echo off
setlocal

REM Query PATH environment value in registry
:QUERY_PATH
    call :GET_REG_VALUE "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "Path"
    call :FILL_ENV_VALUE "%REG_VALUE%"
    set SYSTEM_PATH=%ENV_VALUE%

    call :GET_REG_VALUE "HKEY_CURRENT_USER\Environment" "Path"
    call :FILL_ENV_VALUE "%REG_VALUE%"
    set USER_PATH=%ENV_VALUE%

    echo. & echo SYSTEM_PATH = %SYSTEM_PATH%
    echo. & echo USER_PATH = %USER_PATH%
exit /B

REM Get registry value
REM %1 : reg key
REM %2 : reg value name
REM REG_VALUE : reg value of output
:GET_REG_VALUE <reg_key> <reg_value_name>
    reg query "%~1" /v "%~2"
    for /F "tokens=2* skip=2" %%a in ('reg query "%~1" /v "%~2"') do (
        set REG_VALUE=%%b
    )
exit /B

REM Fill up %ENV_NAME% with environment value
REM %1 : string
REM ENV_VALUE : string of output
:FILL_ENV_VALUE <string>
    for /F "tokens=*" %%s in ('echo "%~1"') do (
        set ENV_VALUE=%%~s
    )
exit /B

Powershell の場合

$SystemPath = (Get-ItemProperty -Path "Registry::HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment").Path
$UserPath = (Get-ItemProperty -Path "Registry::HKCU\Environment").Path
Write-Output "`$SystemPath = $SystemPath"
Write-Output "`$UserPath= $UserPath"

関連記事

14
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
10