やりたいこと
- Windows コマンドスクリプト(.cmd)や PowerShell(.ps1) で環境構築を自動化すべく、chocolatey で git や python をインストールし、続けて git や python を使って環境構築を完結させる。
「スクリプトなんだから続けて書けばいいだけじゃん。」と思うが、そこには落とし穴が。
課題・落とし穴
次の手順をスクリプトとして実装すれば git を使ってリポジトリのクローンまでできそうに思える。
- chocolatey をインストール
- choco install で git をインストール
- インストールされた 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][refreshenv-powershell]
[refreshenv-powershell]:https://stackoverflow.com/questions/46758437/how-to-refresh-the-environment-of-a-powershell-session-after-a-chocolatey-instal)
$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"
関連記事
- [How to refresh the environment of a PowerShell session after a Chocolatey install without needing to open a new session - Stack Overflow][refreshenv-powershell]
- 使うかもしれないレジストリ知識
- reg query
- 変数にレジストリキーの値を読むのに苦労した