記事一覧

C#でシステム環境変数が上手いこと読み込めなかった話




目次




C#のお話

ハロー、みなさん。エジソンです。

最近では、C#を用いたプログラムと、PHPを用いたプログラムの作成を交互に行っています。PHPの記事ばかり書いている僕ですが、C#は個人的に好みです。

静的型付け言語なので、コンパイラで事前にエラー要因を取り除くことができるので、実行時エラーを最小化できます。

これは、スクリプト言語であるPHPのデメリットをカバーしてくれる、コンパイラ言語ならではのメリット(C#に限らない話でもありますが)ですよね。

Related Posts

PHPの悪いところ - デメリット



また、ラムダ式やLINQなど関数型プログラミングのファクターをいち早く取り入れているという、攻めの姿勢も個人的には高評価です。

前置きが長くなりましたが、今回はシステム環境変数のお話です。

システム環境変数の事始め

システム環境変数の代名詞とも言えるのは、「Path」という名前の変数です。

例えば、PostgreSQLをインストールして、DOSプロンプトを開いて psql とタイプすると、PostgreSQLの対話式ユーティリティプログラムを呼び出すことができます。

psqlのファイル本体の場所はと言うと、例えば以下のようなパスに格納されているものとします。

C:¥Program Files¥PostgreSQL¥bin¥psql.exe

一方で、システム環境変数のPathには以下のように設定がされているとします。

Path=...; C:¥Program Files¥PostgreSQL¥bin¥; ...

このように、システム環境変数のPathに、psql.exeが格納されているフォルダが指定されているからこそ、DOSプロンプト上でpsqlとタイプするだけで、psql.exeを呼び出すことができるのですね。

システム環境変数の変更直後に同変数を読み込む場合に注意が必要

先日、はまった事例として、自作インストーラに関する以下のようなものでした。

自作インストーラの処理の一部として、SQLServerをサイレントモードでインストールする仕様がありました。

SQLServerのインストールが完了すると、SQLServerのクライアントユーティリティである SQLCMD.exe のフォルダが、システム環境変数の Path に追記されます。


このような動作仕様を利用するという前提で 、自作インストーラでSQLServerをインストールした後に、システム環境変数のPathを読み取り、SQLCMD.exe のパスを特定するという処理を仕込みました。

システム環境変数を取得するに当たり、以下のメソッドを用いました。

Environment.GetEnvironmentVariable メソッド (String)
現在のプロセスから環境変数の値を取得します。

名前空間: System
アセンブリ: mscorlib (mscorlib.dll 内)
使用例:
System.Console.WriteLine(System.Environment.GetEnvironmentVariable("Path"));

※省略していますが実際の処理では、環境変数のPathを取得してから、セミコロン区切りでパスリストに分解して、それぞれのパスとSQLCMD.exeを結合してファイル存在チェックを実行するというフローになります。

しかしながら、この処理を実際に動かしてみると、SQLCMD.exeは見つからないという結果に終わりました。

何故、このような結果になったかと言うと、上記のメソッドは今現在プロセスで保持している環境変数を読み取るというものだったのです。そのため、プロセスを再起動しない限り、最新の情報は読み取れないという事なのですね。

これに対処するためには、以下のメソッドを代替として用いれば良いかと思います。

Environment.GetEnvironmentVariable メソッド (String, EnvironmentVariableTarget)
環境変数の値を取得します。

取得する場所として、現在のプロセス、現在のユーザー用に予約されている Windows オペレーティング システムのレジストリ キー、および、ローカル コンピューター用に予約されているレジストリ キーのいずれかを選択できます。

名前空間: System
アセンブリ: mscorlib (mscorlib.dll 内)
使用例:
System.Console.WriteLine(System.Environment.GetEnvironmentVariable("Path", System.EnvironmentVariableTarget.Machine));

上記を利用することで、プロセスに関連付けられた環境変数ではなく、最新のシステム環境変数を読み取ることができます。

このエントリーをはてなブックマークに追加

コメント

コメントの投稿

非公開コメント

プロフィール

EZOLABブログへようこそ。
EZOLABは、札幌のソフトウェア会社です。

http://ezolab.co.jp