環境変数あれこれ

Windows の環境変数についてです。環境変数には、システム環境変数ユーザー環境変数の 2 種類があります。
これらは、レジストリの以下の場所に格納されています。

  • システム環境変数

HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment

  • ユーザー環境変数

HKCU\Environment

もちろん、画面でも表示できます。

システムのプロパティ 環境変数

レジストリに書きだしているわけですから、永続化された情報になります。

コマンドプロンプトを開き、set と入力しても環境変数を表示することができます。

コマンドプロンプト_setコマンド

ユーザーが Windows にログオンすると、シェルが起動され、環境変数を読み込みます。
その際、読み込む初期値が、このレジストリにエントリーされている値というわけです。

環境変数って API で参照/設定できないの?って疑問がありますが、Win32API では、残念ながら出来ないです。
上記のレジストリを開き、レジストリ操作系の API を使って、値を参照/設定するか、上記の画面上からの操作になります。

GetEnvironmentVariable() と SetEnvironmentVariable() ですが、これらは、プロセス内で有効な環境ブロックに
アクセスするための API であり、レジストリにエントリーされている環境変数の値を参照/設定するものではありません。
そのため、SetEnvironmentVariable() を使っても、レジストリに値を書きだすことはないです。

    Windows のプロセス内で有効な環境変数は、最初、システム環境変数を読み込んだ後、ユーザー環境変数で
    オーバーライドされます。同じ変数があった場合には、ユーザー環境変数が後勝ちになります。

なお、レジストリで環境変数を変更した場合ですが、ユーザーは一旦 Windows からログオフしてから、
再度、ログオンすることで確実に更新/変更されますが、一部のアプリケーションは、特定のウィンドウメッセージ
(WM_SETTINGCHANGE)を受信すると、再度、環境ブロックを読みだします。

つまり、自分でレジストリをいじったら、SendMessage() や SendMessageTimeout() を使って、
WM_SETTINGCHANGE メッセージを送信してあげるとよいわけです。

DWORD dwReturnValue;
LRESULT Ret = SendMessageTimeout(
                HWND_BROADCAST, WM_SETTINGCHANGE, 0, (LPARAM)TEXT("Environment"),
                SMTO_ABORTIFHUNG, 5000, &dwReturnValue);
if (Ret)
{
    MessageBox(TEXT("環境変数の変更を通知しました。"),
        TEXT("WM_SETTINGCHANGEメッセージ"), MB_OK | MB_ICONINFORMATION);
}

環境変数内には、% で囲まれている文字列があったりしますが、これは、ExpandEnvironmentStrings() を使うことで
展開できます。

例えば、システム環境変数のレジストリを見ると、

名前 種類 データ
ComSpec REG_EXPAND_SZ %SystemRoot%\system32\cmd.exe

というエントリーがあります。これを展開するには、

TCHAR * pszRegValue = TEXT("%SystemRoot%\\system32\\cmd.exe");
TCHAR szExpandPath[MAX_PATH];
ExpandEnvironmentStrings(pszRegValue, szExpandPath, sizeof(szExpandPath));

とすることで、

C:\Windows\system32\cmd.exe

と展開できます。
なお、GetEnvironmentVariable() を使って環境変数を参照する際には、% で囲まれている部分は展開されたものが
返ってきます。

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中

%d人のブロガーが「いいね」をつけました。