Ｗｉｎｄｏｗｓの環境変数の正体！？（種類と保管場所について）

# ⧉Ｗｉｎｄｏｗｓの環境変数の正体！？
Ｗｉｎｄｏｗｓの環境変数についてです。
基本的なことは[Googleで「環境変数とは」を検索][]してください。

## 携帯環境作成支援スクリプト
-Mobile Environment Support Script-
スクリプト作成中に分かったこと、調べたことをまとめた資料です。
トライ・アンド・エラーの途中です。未だ多くの誤りがあると思われます。

〇参考にしたもの
- [Googleで「環境変数とは」を検索][]
- [Microsoft Docs 「環境変数」を検索][]
- [Microsoft Docs 「認識される環境変数」][]
- [Microsoft Docs 「setコマンド」][]
- [Microsoft Docs 「setxコマンド」][]
- [Microsoft Docs 「regコマンド」][]

### ◇環境変数の種類と変数の保管場所
環境変数は主にレジストリに記録されています。
基本的には次の４つに分類され、それぞれの保管場所は次のとおりです。

- **SYSTEM** - システム環境変数
レジストリの次の場所にに記録されています。
`HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment`

- **USER** - ユーザー環境変数
レジストリの次の場所にに記録されています。
`HKEY_CURRENT_USER\Environment`

- **VOLATILE** - 揮発性環境変数
レジストリの次の場所にに記録されています。
`HKEY_CURRENT_USER\Volatile Environment`

    ログイン中のみ記録される仕様となっていると思われますが、ログアウトやシャットダウンしても消えないことがあります。
原因は不明ですが、追及をするのはやめました。
また、揮発性であるにも関わらずデフォルトの変数がありキーを削除してもデフォルト設定は再起動時に復活します。
普通に削除する場合、値が空になるように設定しますがキーは残ってしまいます。
完全に削除したい場合はレジストリエディターやREGコマンドで削除します。

- **PROCESS** - プロセス環境変数
プロセス環境変数は新規にプロセスを作成、実行したときにレジストリから`SYSTEM`、`USER`、`VOLATILE`の順に読み込まれ、プロセスごとに作成されます。
レジストリには記録されず実行中のプロセス内でのみ有効です。
環境変数"PATH"は追記され、それ以外の同名の変数は順に上書きされます。
レジストリから読み込まれるのは***新規にプロセスを作成、実行したときのみ***です。
つまりプロセスから`SYSTEM`、`USER`、`VOLATILE`のいずれかに変数を書き込んでも実行中のプロセスには影響しません。
また、実行中のプロセスから別のプロセスを作成、実行した場合も環境変数はレジストリから読み込まれません。
実行中のプロセスと実行中のプロセスから作成、実行したプロセスには**プロセス環境変数**のみ影響します。

### ◇環境変数の設定方法とレジストリへの書き込み
大別すると環境変数はレジストリで管理される`SYSTEM`、`USER`、`VOLATILE`環境変数と
プロセスごとにメモリ内に作成される`PROCESS`環境変数に分けられることになります。
レジストリ書き込み型の環境変数とプロセス環境変数の両方に書き込むとプロセスへ即時反映と他のプロセスへの引き継ぎができます。

#### 〇レジストリへの書き込み「システムのプロパティ」画面の呼び出し方法
設定から呼び出すのが普通ですが、ショートカットを作るのと楽です。
`C:\Windows\System32\SystemPropertiesAdvanced.exe`
を実行します。

#### 〇レジストリへの書き込み「REGコマンド」の使い方
- [Microsoft Docs 「regコマンド」][]
※HKEY_CURRENT_USER以外のキーを操作する時は管理者権限が必要です。

取り扱いにミスしても被害が少ないVOLATILE環境変数を例にしてしています。

- レジストリキーの参照
`reg query "HKEY_CURRENT_USER\Volatile Environment"`
- レジストリキーの削除（再起動時、デフォルト設定が書き込まれます。）
`reg delete "HKEY_CURRENT_USER\Volatile Environment"`
- レジストリキーの値を追加
`reg add "HKEY_CURRENT_USER\Volatile Environment" /v "TEST" /t REG_EXPAND_SZ /d "TEST_DATA" /f`
- レジストリキーの値を消去（デフォルトの処理はこちらです。参照はできなくなりますがゴミが残ります。）
`reg add "HKEY_CURRENT_USER\Volatile Environment" /v "TEST" /t REG_EXPAND_SZ /d "" /f`
- レジストリキーの値を削除（レジストリから削除します。）
`reg delete "HKEY_CURRENT_USER\Volatile Environment" /v "TEST" /f`

#### 〇レジストリキーの名前の省略について

- HKEY_CLASSES_ROOT   -> HKCR
- HKEY_CURRENT_USER   -> HKCU
- HKEY_LOCAL_MACHINE  -> HKLM
- HKEY_USERS          -> HKU
- HKEY_CURRENT_CONFIG -> HKCC

### ◇環境変数"PATH"っぽいもの
環境変数"PATH"へ設定をしていなくても起動または優先されるアプリケーションがあります。
分かっている仕組みは2つ「アプリ実行エイリアス」とレジストリ「App Paths」です。

- アプリ実行エイリアス
「設定」「アプリと機能」「アプリ実行エイリアス」からオン、オフのみできます。
Pythonの環境設定をしている時に気づきました。なんのためにあるものなのか不明。
人気のPythonを利用してストアへの誘導が目的？害悪としか言えない仕様だと思います。

- App Paths
`HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths`
`HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\App Paths`
Win+Rの「ファイル名を指定して実行」などで反映されるようです。
コマンドプロンプト以外に適用されるのかもしれません。
WinRARがコマンドプロンプトから実行できないことで偶然、気づきました。
GUIアプリケーションと区別するものかもしれませんが、`rar.exe`のようなアプリケーションもあるので、
利用するアプリ側の問題とも言えますが、もう少しスマートな実装ができなかったのでしょうか。

## お粗末様でした。
最後までお読みいただきありがとうございます。
この資料は[携帯環境作成支援スクリプト][]を作成する過程で作成されたものです。
スクリプトはGitHUbで公開しています。ご興味ある方はそちらもぜひご覧ください。
https://github.com/Aromatibus/MECCS

[携帯環境作成支援スクリプト]: https://github.com/Aromatibus/MECCS
[Googleで「環境変数とは」を検索]: https://www.google.co.jp/search?q=windows+環境変数とは
[Microsoft Docs 「環境変数」を検索]: https://docs.microsoft.com/ja-jp/search/?terms=環境変数
[Microsoft Docs 「setコマンド」]: https://docs.microsoft.com/ja-jp/windows-server/administration/windows-commands/set
[Microsoft Docs 「setxコマンド」]: https://docs.microsoft.com/ja-jp/windows-server/administration/windows-commands/setx
[Microsoft Docs 「認識される環境変数」]: https://docs.microsoft.com/ja-jp/windows/deployment/usmt/usmt-recognized-environment-variables
[Microsoft Docs 「regコマンド」]: https://docs.microsoft.com/ja-jp/windows-server/administration/windows-commands/reg