System.EnvironmentクラスのGetEnvironmentVariableメソッドSetEnvironmentVariableメソッドを用いることにより、プロセスの環境変数の取得設定をすることができます。 子プロセスを起動する場合には、ProcessStartInfo.EnvironmentVariablesプロパティを用いることにより環境変数を追加・削除・変更して子プロセスを起動することができます。

ここでは主にプロセスの環境変数を中心として、環境変数の取り扱いに関する事項を扱います。

環境変数の取得

名前を指定した環境変数の取得 (Environment.GetEnvironmentVariable)

Environment.GetEnvironmentVariableメソッドを使うことで現在のプロセスの環境変数を取得することができます。 このメソッドは、指定された名前の環境変数が設定されていればその値を、設定されていない場合はnull/Nothingを返します。 Windowsでは、このメソッドは環境変数の名前における大文字小文字の違いを無視します。 Linux等では大文字小文字の異なる環境変数は異なるものとして扱われます。

Environment.GetEnvironmentVariableメソッドを使って特定の環境変数を取得する
using System;

class Sample {
  static void Main()
  {
    // 環境変数 'PATH' を取得・表示
    Console.WriteLine("PATH={0}", Environment.GetEnvironmentVariable("PATH"));

    // 環境変数 'Path' を取得・表示 (Windows上では大文字小文字の違いは無視される)
    Console.WriteLine("Path={0}", Environment.GetEnvironmentVariable("Path"));
  }
}
Environment.GetEnvironmentVariableメソッドを使って特定の環境変数を取得する
Imports System

Class Sample
  Shared Sub Main()
    ' 環境変数 'PATH' を取得・表示
    Console.WriteLine("PATH={0}", Environment.GetEnvironmentVariable("PATH"))

    ' 環境変数 'Path' を取得・表示 (Windows上では大文字小文字の違いは無視される)
    Console.WriteLine("Path={0}", Environment.GetEnvironmentVariable("Path"))
  End Sub
End Class
実行結果例(Windows 10 + .NET Framework 4.6)
PATH=C:\ProgramData\Oracle\Java\javapath;C:\Program Files\Common Files\Microsoft Shared\Windows Live;C:\Program Files (x86)\Common Files\Microsoft Shared\Windows Live;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\Windows Live\Shared;C:\Program Files\Intel\WiFi\bin\;C:\Program Files\Common Files\Intel\WirelessCommon\;C:\Program Files\Intel\WiFi\bin\;C:\Program Files\Common Files\Intel\WirelessCommon\;C:\Windows\Microsoft.NET\Framework\v4.0.30319
Path=C:\ProgramData\Oracle\Java\javapath;C:\Program Files\Common Files\Microsoft Shared\Windows Live;C:\Program Files (x86)\Common Files\Microsoft Shared\Windows Live;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\Windows Live\Shared;C:\Program Files\Intel\WiFi\bin\;C:\Program Files\Common Files\Intel\WirelessCommon\;C:\Program Files\Intel\WiFi\bin\;C:\Program Files\Common Files\Intel\WirelessCommon\;C:\Windows\Microsoft.NET\Framework\v4.0.30319
実行結果例(Ubuntu 14.04 + Mono 4.2)
PATH=/opt/mono/4.2/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
Path=

大文字小文字の違いが異なる環境変数を別のものとして扱いたい場合は、Environment.GetEnvironmentVariablesメソッドを使うことができます。

すべての環境変数の取得 (Environment.GetEnvironmentVariables)

Environment.GetEnvironmentVariablesメソッドを使うと、現在のプロセスの環境変数すべてを取得できます。 このメソッドは環境変数の名前をエントリのキー、環境変数の値をエントリのとするIDictionary (ディクショナリ)を返します。

このメソッドが返すIDictionaryは大文字小文字の違いをチェックするため、大文字小文字を正しく指定しないと環境変数を取得できません。

Environment.GetEnvironmentVariablesメソッドを使ってすべての環境変数を取得する
using System;
using System.Collections;

class Sample {
  static void Main()
  {
    // すべての環境変数を取得
    IDictionary envvars = Environment.GetEnvironmentVariables();

    // 環境変数 'PATH' を取得・表示 (大文字小文字の違いがチェックされる点に注意)
    Console.WriteLine("PATH={0}", envvars["PATH"]);
    Console.WriteLine("Path={0}", envvars["Path"]);

    Console.WriteLine();

    // すべての環境変数を列挙して表示
    foreach (DictionaryEntry entry in envvars) {
      Console.WriteLine("{0}=>{1}", entry.Key, entry.Value);
    }
  }
}
Environment.GetEnvironmentVariablesメソッドを使ってすべての環境変数を取得する
Imports System
Imports System.Collections

Class Sample
  Shared Sub Main()
    ' すべての環境変数を取得
    Dim envvars As IDictionary = Environment.GetEnvironmentVariables()

    ' 環境変数 'PATH' を取得・表示 (大文字小文字の違いがチェックされる点に注意)
    Console.WriteLine("Path={0}", envvars("Path"))
    Console.WriteLine("PATH={0}", envvars["PATH"])
    Console.WriteLine()

    ' すべての環境変数を列挙して表示
    For Each entry As DictionaryEntry In envvars
      Console.WriteLine("{0} => {1}", entry.Key, entry.Value)
    Next
  End Sub
End Class
実行結果例(Windows 10 + .NET Framework 4.6)
PATH=
Path=C:\ProgramData\Oracle\Java\javapath;C:\Program Files\Common Files\Microsoft Shared\Windows Live;C:\Program Files (x86)\Common Files\Microsoft Shared\Windows Live;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\Windows Live\Shared;C:\Program Files\Intel\WiFi\bin\;C:\Program Files\Common Files\Intel\WirelessCommon\;C:\Program Files\Intel\WiFi\bin\;C:\Program Files\Common Files\Intel\WirelessCommon\;C:\Windows\Microsoft.NET\Framework\v4.0.30319

COMPUTERNAME => LUNAR
HOMEPATH => \Users\smdn
LOCALAPPDATA => C:\Users\smdn\AppData\Local
  :
  :
(以下略)
実行結果例(Ubuntu 14.04 + Mono 4.2)
PATH=/opt/mono/4.2/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
Path=

LANG=>ja_JP.UTF-8
USER=>smdn
HOME=>/home/smdn
  :
  :
(以下略)

IDictionaryの列挙、DictionaryEntry構造体についてはHashtableクラス §.列挙操作を参照してください。


環境変数名の大文字小文字の違いを無視するようにするには、次の例のようにStringComparer.OrdinalIgnoreCaseを用いてキーの大文字小文字の違いを無視するようなDictionaryを作成し、そこにEnvironment.GetEnvironmentVariablesメソッドの結果をコピーした上で環境変数を参照します。

Dictionaryを使って環境変数名の大文字小文字の違いを無視して扱う
using System;
using System.Collections;
using System.Collections.Generic;

class Sample {
  static void Main()
  {
    // 大文字小文字の違いを無視するDictionaryを作成
    Dictionary<string, string> envvars = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);

    // 環境変数を取得してDictionaryにコピー
    foreach (DictionaryEntry entry in Environment.GetEnvironmentVariables()) {
      envvars.Add((string)entry.Key, (string)entry.Value);
    }

    // 環境変数をコピーしたDictionaryを使って参照
    Console.WriteLine("Path={0}", envvars["Path"]);
    Console.WriteLine("PATH={0}", envvars["PATH"]);
    Console.WriteLine("path={0}", envvars["path"]);
  }
}
Dictionaryを使って環境変数名の大文字小文字の違いを無視して扱う
Imports System
Imports System.Collections
Imports System.Collections.Generic

Class Sample
  Shared Sub Main()
    ' 大文字小文字の違いを無視するDictionaryを作成
    Dim envvars As New Dictionary(Of String, String)(StringComparer.OrdinalIgnoreCase)

    ' 環境変数を取得してDictionaryにコピー
    For Each entry As DictionaryEntry In Environment.GetEnvironmentVariables()
      envvars.Add(DirectCast(entry.Key, String), DirectCast(entry.Value, String))
    Next

    ' 環境変数をコピーしたDictionaryを使って参照
    Console.WriteLine("Path={0}", envvars("Path"))
    Console.WriteLine("PATH={0}", envvars("PATH"))
    Console.WriteLine("path={0}", envvars("path"))
  End Sub
End Class
実行結果例(Windows 10 + .NET Framework 4.6)
Path=C:\ProgramData\Oracle\Java\javapath;C:\Program Files\Common Files\Microsoft Shared\Windows Live;C:\Program Files (x86)\Common Files\Microsoft Shared\Windows Live;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\Windows Live\Shared;C:\Program Files\Intel\WiFi\bin\;C:\Program Files\Common Files\Intel\WirelessCommon\;C:\Program Files\Intel\WiFi\bin\;C:\Program Files\Common Files\Intel\WirelessCommon\;C:\Windows\Microsoft.NET\Framework\v4.0.30319
PATH=C:\ProgramData\Oracle\Java\javapath;C:\Program Files\Common Files\Microsoft Shared\Windows Live;C:\Program Files (x86)\Common Files\Microsoft Shared\Windows Live;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\Windows Live\Shared;C:\Program Files\Intel\WiFi\bin\;C:\Program Files\Common Files\Intel\WirelessCommon\;C:\Program Files\Intel\WiFi\bin\;C:\Program Files\Common Files\Intel\WirelessCommon\;C:\Windows\Microsoft.NET\Framework\v4.0.30319
path=C:\ProgramData\Oracle\Java\javapath;C:\Program Files\Common Files\Microsoft Shared\Windows Live;C:\Program Files (x86)\Common Files\Microsoft Shared\Windows Live;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\Windows Live\Shared;C:\Program Files\Intel\WiFi\bin\;C:\Program Files\Common Files\Intel\WirelessCommon\;C:\Program Files\Intel\WiFi\bin\;C:\Program Files\Common Files\Intel\WirelessCommon\;C:\Windows\Microsoft.NET\Framework\v4.0.30319
実行結果例(Ubuntu 14.04 + Mono 4.2)
Path=/opt/mono/2.10/bin:/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
PATH=/opt/mono/2.10/bin:/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
path=/opt/mono/2.10/bin:/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games

Dictionaryと大文字小文字の違いの無視についてはジェネリックコレクション(2) Dictionary §.キー比較のカスタマイズ(大文字小文字の違いの無視)、StringComparerについては文字列と比較オプション・カルチャの並べ替え規則で詳しく解説しています。

環境変数の追加・変更・削除 (Environment.SetEnvironmentVariable)

環境変数を追加・変更・削除するにはEnvironment.SetEnvironmentVariableメソッドを使うことができます。

SetEnvironmentVariableメソッドで存在しない環境変数名を指定すれば、その名前で環境変数を追加することができます。 すでに同じ名前の環境変数が存在する場合は、環境変数の値が変更されます。 環境変数の値としてnull/Nothingや空の文字列(String.Empty)を指定した場合、その環境変数は削除されます。

Environment.SetEnvironmentVariableを使ってプロセスの環境変数を追加・変更・削除する
using System;

class Sample {
  static void Main()
  {
    // 環境変数 'PATH_DATA' の値を変更 (環境変数が存在しない場合は追加される)
    Environment.SetEnvironmentVariable("PATH_DATA", @".\data\");

    // 環境変数 'PATH_DATA' の値を変更 (環境変数が存在しているので値が変更される)
    Environment.SetEnvironmentVariable("PATH_DATA", @".\data2\");

    // 環境変数 'PATH_DATA' を削除 (環境変数が存在しない場合でも例外にはならない)
    Environment.SetEnvironmentVariable("PATH_DATA", null);
    Environment.SetEnvironmentVariable("PATH_DATA", string.Empty);
  }
}
Environment.SetEnvironmentVariableを使ってプロセスの環境変数を追加・変更・削除する
Imports System

Class Sample
  Shared Sub Main()
    ' 環境変数 'PATH_DATA' の値を変更 (環境変数が存在しない場合は追加される)
    Environment.SetEnvironmentVariable("PATH_DATA", ".\data\")

    ' 環境変数 'PATH_DATA' の値を変更 (環境変数が存在しているので値が変更される)
    Environment.SetEnvironmentVariable("PATH_DATA", ".\data2\")

    ' 環境変数 'PATH_DATA' を削除 (環境変数が存在しない場合でも例外にはならない)
    Environment.SetEnvironmentVariable("PATH_DATA", Nothing)
    Environment.SetEnvironmentVariable("PATH_DATA", String.Empty)
  End Sub
End Class

環境変数の設定・取得の対象 (EnvironmentVariableTarget)

Environment.SetEnvironmentVariableメソッドでは、変更する環境変数の対象を指定するEnvironmentVariableTarget列挙体を同時に指定することができます。

EnvironmentVariableTargetを指定しなかった場合はプロセスの環境変数を変更しますが、レジストリに保存されている環境変数を変更する場合はEnvironmentVariableTargetを指定します。 例えば、システムで設定されている環境変数PATHの値を変更したいといった場合にはEnvironmentVariableTarget.MachineEnvironmentVariableTarget.Userを指定します。

EnvironmentVariableTargetで指定できる値と、変更対象は次のとおりです。

EnvironmentVariableTargetと変更される環境変数の対象
EnvironmentVariableTargetの値 変更対象の環境変数
EnvironmentVariableTarget.Machine レジストリに保存されているシステムに共通の環境変数
(レジストリキーHKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environmentの環境変数)
EnvironmentVariableTarget.User レジストリに保存されているユーザー別の環境変数
(レジストリキーHKEY_CURRENT_USER\Environmentの環境変数)
EnvironmentVariableTarget.Process プロセスの環境変数
(EnvironmentVariableTargetを指定しなかった場合と同じ)

Environment.GetEnvironmentVariableメソッドでも同様にEnvironmentVariableTargetを指定して環境変数の取得対象を指定することができます。

環境変数の展開 (Environment.ExpandEnvironmentVariables)

Environment.ExpandEnvironmentVariablesメソッドを使うと、文字列内に含まれる環境変数(%ENVVAR%)を展開して環境変数に設定されている値に置換することができます。 文字列内に複数の環境変数が存在する場合は、そのすべてが置換されます。

Environment.ExpandEnvironmentVariablesメソッドを使って文字列内の環境変数を展開する
using System;

class Sample {
  static void Main()
  {
    // 展開される環境変数
    Environment.SetEnvironmentVariable("PATH_DATA", @".\data\");

    // 文字列内に含まれる環境変数を展開する
    var filepath = Environment.ExpandEnvironmentVariables("%PATH_DATA%file.txt");

    Console.WriteLine(filepath);
  }
}
Environment.ExpandEnvironmentVariablesメソッドを使って文字列内の環境変数を展開する
Imports System

Class Sample
  Shared Sub Main()
    ' 展開される環境変数
    Environment.SetEnvironmentVariable("PATH_DATA", ".\data\")

    ' 文字列内に含まれる環境変数を展開する
    Dim filepath As String = Environment.ExpandEnvironmentVariables("%PATH_DATA%file.txt")

    Console.WriteLine(filepath)
  End Sub
End Class
実行結果
.\data\file.txt

環境変数PATHのように複数のパスが指定されている場合は、展開される際にパスが分割されるといったことはなく、指定されている値がそのまま展開されます。 環境変数に設定されているパスを分解して展開したい場合は§.実行可能ファイルの検索などで掲載しているような方法をとる必要があります。


環境変数が存在しない場合は、%ENVVAR%の表記は置換されずにそのまま維持されます。 空の文字列に展開されて削除されるといった動作にはなりません。

環境変数が存在しない場合、Environment.ExpandEnvironmentVariablesメソッドは環境変数を展開しない
using System;

class Sample {
  static void Main()
  {
    // 環境変数 'PATH_DATA' を削除する
    Environment.SetEnvironmentVariable("PATH_DATA", null);

    // 文字列内に含まれる環境変数を展開する
    // (環境変数が存在しないので展開されないままになる)
    var filepath = Environment.ExpandEnvironmentVariables("%PATH_DATA%file.txt");

    Console.WriteLine(filepath);
  }
}
環境変数が存在しない場合、Environment.ExpandEnvironmentVariablesメソッドは環境変数を展開しない
Imports System

Class Sample
  Shared Sub Main()
    ' 環境変数 'PATH_DATA' を削除する
    Environment.SetEnvironmentVariable("PATH_DATA", Nothing)

    ' 文字列内に含まれる環境変数を展開する
    ' (環境変数が存在しないので展開されないままになる)
    Dim filepath As String = Environment.ExpandEnvironmentVariables("%PATH_DATA%file.txt")

    Console.WriteLine(filepath)
  End Sub
End Class
実行結果
%PATH_DATA%file.txt

環境変数PATH

パスの分割

通常、環境変数PATHには複数のパスが含まれる場合がほとんどで、Environment.GetEnvironmentVariableメソッドなどで環境変数PATHを取得した場合は複数のパスが連結された状態で取得されます。

連結されたPATHを分割するにはString.Splitメソッド(文字列の加工・編集 §.分割 (Split))を用いることができます。 WindowsではPATHの区切り文字には";"、Linuxなどでは":"が用いられますが、この区切り文字はPath.PathSeparatorフィールドを参照することで取得でき、これをSplitメソッドに渡すことで実行環境に応じた区切り文字での分割を行うことができます。

String.Splitメソッドを使って環境変数PATHを分割する
using System;
using System.IO;

class Sample {
  static void Main()
  {
    // 環境変数 'PATH' を取得
    string paths = Environment.GetEnvironmentVariable("PATH");

    Console.WriteLine(paths);
    Console.WriteLine();

    // 'PATH' をパス区切り文字で分割して表示
    foreach (var path in paths.Split(Path.PathSeparator)) {
      Console.WriteLine(path);
    }
  }
}
String.Splitメソッドを使って環境変数PATHを分割する
Imports System
Imports System.IO

Class Sample
  Shared Sub Main()
    ' 環境変数 'PATH' を取得
    Dim paths As String = Environment.GetEnvironmentVariable("PATH")

    Console.WriteLine(paths)
    Console.WriteLine("Path.PathSeparator = '{0}'", Path.PathSeparator)
    Console.WriteLine()

    ' 'PATH' をパス区切り文字で分割して表示
    For Each path As String In paths.Split(Path.PathSeparator)
      Console.WriteLine(path)
    Next
  End Sub
End Class
実行結果例(Windows 10 + .NET Framework 4.6)
C:\ProgramData\Oracle\Java\javapath;C:\Program Files\Common Files\Microsoft Shared\Windows Live;C:\Program Files (x86)\Common Files\Microsoft Shared\Windows Live;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\Windows Live\Shared;C:\Program Files\Intel\WiFi\bin\;C:\Program Files\Common Files\Intel\WirelessCommon\;C:\Program Files\Intel\WiFi\bin\;C:\Program Files\Common Files\Intel\WirelessCommon\;C:\Windows\Microsoft.NET\Framework\v4.0.30319

C:\ProgramData\Oracle\Java\javapath
C:\Program Files\Common Files\Microsoft Shared\Windows Live
C:\Program Files (x86)\Common Files\Microsoft Shared\Windows Live
C:\WINDOWS\system32
C:\WINDOWS
C:\WINDOWS\System32\Wbem
C:\WINDOWS\System32\WindowsPowerShell\v1.0\
C:\Program Files (x86)\Windows Live\Shared
C:\Program Files\Intel\WiFi\bin\
C:\Program Files\Common Files\Intel\WirelessCommon\
C:\Program Files\Intel\WiFi\bin\
C:\Program Files\Common Files\Intel\WirelessCommon\
C:\Windows\Microsoft.NET\Framework\v4.0.30319
実行結果例(Ubuntu 14.04 + Mono 4.2)
/opt/mono/4.2/bin:/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games

/opt/mono/4.2/bin
/usr/lib/lightdm/lightdm
/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
/sbin
/bin
/usr/games

Pathクラスを用いてパスをディレクトリ単位で分割したり結合したりする方法についてはパスの操作を参照してください。

実行可能ファイルの検索

whereコマンド(Windows)・whichコマンド(Linux)のようにコマンド名から実行可能ファイルのフルパスを取得するには、環境変数PATHに設定されているディレクトリを一つずつ走査して実行可能ファイルが存在するかどうかを調べる必要があります。

以下はwhichコマンドと同等の動作をするコードです。

PATH環境変数を取得して実行可能ファイルのフルパスを検索する
using System;
using System.IO;

class Which {
  // 引数に与えられたコマンド名から実行可能ファイルのフルパスを検索する
  // 0: 指定されたコマンドがすべて見つかった
  // 1: いくつかのコマンドが見つからない
  static int Main(string[] args)
  {
    var foundAll = false;

    foreach (var command in args) {
      var found = false;
      string fullpath = null;

      foreach (var dir in Environment.GetEnvironmentVariable("PATH").Split(Path.PathSeparator)) {
        // PATH環境変数のディレクトリとコマンド名を連結して、ファイルが存在するか調べる
        fullpath = Path.Combine(dir, command);

        if (File.Exists(fullpath)) {
          // ディレクトリ内にコマンドが見つかった
          found = true;
          break;
        }

        // Windowsの場合はコマンド名に".exe"を付加して再検索
        if (Environment.OSVersion.Platform != PlatformID.Unix) {
          fullpath += ".exe";

          if (File.Exists(fullpath)) {
            found = true;
            break;
          }
        }
      }

      foundAll &= found;

      if (found)
        Console.WriteLine(fullpath);
    }

    return foundAll ? 0 : 1;
  }
}
PATH環境変数を取得して実行可能ファイルのフルパスを検索する
Imports System
ImportS System.IO

Class Which
  ' 引数に与えられたコマンド名から実行可能ファイルのフルパスを検索する
  ' 0: 指定されたコマンドがすべて見つかった
  ' 1: いくつかのコマンドが見つからない
  Shared Sub Main(ByVal args() As String)
    Dim foundAll As Boolean = False

    For Each command As String In args
      Dim found As Boolean = False
      Dim fullpath As String = Nothing

      For Each dir As String In Environment.GetEnvironmentVariable("PATH").Split(Path.PathSeparator)
        ' PATH環境変数のディレクトリとコマンド名を連結して、ファイルが存在するか調べる
        fullpath = Path.Combine(dir, command)

        If File.Exists(fullpath) Then
          ' ディレクトリ内にコマンドが見つかった
          found = True
          Exit For
        End If

        ' Windowsの場合はファイル名に".exe"を付加して再検索
        If Environment.OSVersion.Platform <> PlatformID.Unix Then
          fullpath += ".exe"

          If File.Exists(fullpath) Then
            found = True
            Exit For
          End If
        End If
      Next

      foundAll = foundAll AndAlso found

      If found Then
        Console.WriteLine(fullpath)
      End If
    Next

    Return IIf(foundAll, 0, 1)
  End Sub
End Class
実行結果例(Windows 10 + .NET Framework 4.6)
>where csc notepad where foo
C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe
C:\Windows\System32\notepad.exe
C:\Windows\notepad.exe
C:\Windows\System32\where.exe
情報: "foo" が見つかりませんでした。

>which.exe csc notepad where foo
C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe
C:\WINDOWS\system32\notepad.exe
C:\WINDOWS\system32\where.exe
実行結果例(Ubuntu 14.04 + Mono 4.2)
$which mono mcs which foo
/opt/mono/4.2/bin/mono
/opt/mono/4.2/bin/mcs
/usr/bin/which

$mono which.exe mono mcs which foo
/opt/mono/4.2/bin/mono
/opt/mono/4.2/bin/mcs
/usr/bin/which

パスの追加

環境変数PATHに別のパスを追加する場合も、分割の場合と同様にPath.PathSeparatorフィールドからパス区切り文字を取得して次のようにします。

PATH環境変数に別のパスを追加する
using System;
using System.IO;

class Sample {
  static void Main()
  {
    // カレントディレクトリのフルパスを取得する
    var currentdir = Path.GetFullPath(Environment.CurrentDirectory);

    // 環境変数 'PATH' にcurrentdirを追加する
    var path = Environment.GetEnvironmentVariable("PATH");

    Environment.SetEnvironmentVariable("PATH", path + Path.PathSeparator + currentdir);
  }
}
PATH環境変数に別のパスを追加する
Imports System
Imports System.IO

Class Sample
  Shared Sub Main()
    ' カレントディレクトリのフルパスを取得する
    Dim currentdir As String = Path.GetFullPath(Environment.CurrentDirectory)

    ' 環境変数 'PATH' にcurrentdirを追加する
    Dim p As String = Environment.GetEnvironmentVariable("PATH")

    Environment.SetEnvironmentVariable("PATH", p + Path.PathSeparator + currentdir)
  End Sub
End Class

環境変数PATHの値を分割してListに格納し、編集した上で再設定する場合は次のようにします。

PATH環境変数の内容を分割してListに変換し、編集する
using System;
using System.Collections.Generic;
using System.IO;

class Sample {
  static void Main()
  {
    // 環境変数 'PATH' に設定されているパスを分割してListにする
    var paths = new List<string>(Environment.GetEnvironmentVariable("PATH").Split(Path.PathSeparator));

    // Listにカレントディレクトリのフルパスを追加する
    paths.Add(Path.GetFullPath(Environment.CurrentDirectory));

    // Listの内容を再結合して環境変数 'PATH' に設定しなおす
    Environment.SetEnvironmentVariable("PATH", string.Join(Path.PathSeparator.ToString(), paths));
  }
}
PATH環境変数の内容を分割してListに変換し、編集する
Imports System
Imports System.Collections.Generic
Imports System.IO

Class Sample
  Shared Sub Main()
    ' 環境変数 'PATH' に設定されているパスを分割してListにする
    Dim paths As New List(Of String)(Environment.GetEnvironmentVariable("PATH").Split(Path.PathSeparator))

    ' Listにカレントディレクトリのフルパスを追加する
    paths.Add(Path.GetFullPath(Environment.CurrentDirectory))

    ' Listの内容を再結合して環境変数 'PATH' に設定しなおす
    Environment.SetEnvironmentVariable("PATH", string.Join(Path.PathSeparator.ToString(), paths))
  End Sub
End Class

環境変数PATHにパスを追加して子プロセス(外部アプリケーション)を起動する方法については§.子プロセスの環境変数も参照してください。

Listクラスの扱い方についてはジェネリックコレクション(1) Listを参照してください。

子プロセスの環境変数

Process.Startメソッドなどによって子プロセス(外部アプリケーション)を起動する際、環境変数は起動した子プロセスにも引き継がれるため、Environment.SetEnvironmentVariableメソッドによって設定した環境変数は子プロセスでも同じ値が用いられます。 一方、ProcessStartInfoクラスを用いることによって、起動する子プロセスの環境変数だけを設定することができます。

特に環境変数を設定しない場合は親プロセスの環境変数がそのまま引き継がれますが、ProcessStartInfo.EnvironmentVariablesプロパティを設定することで、親プロセスの環境変数を上書き(あるいは変更・削除)した状態で子プロセスを起動することができます。 親プロセスとは異なる環境変数で子プロセスを実行させたい場合にはこのプロパティを使って環境変数を変更します。

EnvironmentVariablesプロパティで環境変数の値としてnull/Nothingや空の文字列(String.Emptyを指定した場合、その環境変数は削除されます。 EnvironmentVariablesプロパティを変更する場合、Windows環境では大文字小文字の違いは無視されます。 一方、Linux等では大文字小文字の違いが意識される点に注意してください(大文字小文字が異なる環境変数名は別のものとして扱われます)。

環境変数を変更して子プロセスを起動する
using System;
using System.IO;
using System.Diagnostics;

class Sample {
  static void Main()
  {
    // 子プロセスchild.exeの起動パラメータを作成する
    var psi = new ProcessStartInfo("child.exe");

    // シェルを使用せずに子プロセスを起動する
    // (環境変数を設定する場合にはfalseにする必要がある)
    psi.UseShellExecute = false;

    // 子プロセスの環境変数 'PATH_DATA' を設定する
    psi.EnvironmentVariables["PATH_DATA"] = @".\data\";

    // 子プロセスの環境変数 'PATH_LIBS' を削除する
    psi.EnvironmentVariables["PATH_LIBS"] = null;

    // 子プロセスの環境変数 'PATH' に別のパスを追加する
    psi.EnvironmentVariables["PATH"] += (Path.PathSeparator + Path.Combine(".", "new", "path"));

    // 上記のパラメータで子プロセスを起動する
    using (var child = Process.Start(psi)) {
      // 子プロセスの終了を待機する
      child.WaitForExit();
    }
  }
}
環境変数を変更して子プロセスを起動する
Imports System
Imports System.IO
Imports System.Diagnostics

Class Sample
  Shared Sub Main()
    ' 子プロセスchild.exeの起動パラメータを作成する
    Dim psi As New ProcessStartInfo("child.exe")

    ' シェルを使用せずに子プロセスを起動する
    ' (環境変数を設定する場合にはFalseにする必要がある)
    psi.UseShellExecute = False

    ' 子プロセスの環境変数 'PATH_DATA' を設定する
    psi.EnvironmentVariables("PATH_DATA") = ".\data\"

    ' 子プロセスの環境変数 'PATH_LIBS' を削除する
    psi.EnvironmentVariables("PATH_LIBS") = Nothing

    ' 子プロセスの環境変数 'PATH' に別のパスを追加する
    psi.EnvironmentVariables("PATH") += (Path.PathSeparator + Path.Combine(".", "new", "path"))

    ' 上記のパラメータで子プロセスを起動する
    Using child As Process = Process.Start(psi)
      ' 子プロセスの終了を待機する
      child.WaitForExit()
    End Using
  End Sub
End Class

Process.Startメソッドによるプロセスの起動では、コマンド・実行可能ファイルの検索に際して環境変数PATHの値が参照されます。 環境変数PATHが適切に設定されていれば、フルパスを指定しなくてもコマンド・実行可能ファイルを起動することができます。

この他、子プロセスの起動や、プロセス起動時のオプションについてはプロセス §.子プロセスの起動オプションを参照してください。 また、Pathクラスによるパスの分割・結合などの操作についてはパスの操作を参照してください。

環境変数と代替機能

ロケール情報(環境変数LANG・環境変数LC_*)

Windowsではコントロールパネルの地域と言語のオプションが用いられるため、環境変数LANGの設定は実行時の動作に影響しません。 一方Linux等では環境変数LANGの設定に応じたロケールが用いられます。 詳しくはカルチャの基本・種類・カルチャ情報の取得 §.作成したスレッドのカルチャを参照してください。

また、LC_ALLLC_NUMERICLC_TIMEなどロケールに関する設定は、.NET FrameworkにおいてはカルチャとしてCultureInfoクラスによって扱われ、スレッド毎に設定・変更することができます。 詳しくはカルチャの基本・種類・カルチャ情報の取得およびカルチャと書式・テキスト処理・暦を参照してください。

システムディレクトリ・ホームディレクトリなどの取得

システムディレクトリ(%SystemRoot%)・ホームディレクトリ(%USERPROFILE%, HOME)・一時ディレクトリ(%TEMP%)など、システムで定義されている特殊なディレクトリは、環境変数から直接取得するよりもEnvironment.GetFolderPathメソッドを使うことによって取得することが推奨されます。

Environment.GetFolderPathメソッドを使った各種ディレクトリのパスの取得についてはランタイム・システム・プラットフォームの情報 §.特別なディレクトリで解説しています。

一時ディレクトリ(TMPTEMP)・一時ファイルについては一時ディレクトリを取得する・一時ファイルを作成するを参照してください。

プラットフォーム・実行環境の情報の取得

プラットフォームや実行環境など、環境変数からでは取得できない情報の取得に関してはランタイム・システム・プラットフォームの情報およびプロセス・アセンブリの情報で解説しています。

実行時の動作変更

.NET Frameworkでは、実行時の動作オプションを指定する目的にXML形式のアプリケーション構成ファイル(*.exe.config)を用いることができます。 .NETランタイムのオプションを設定する場合にも構成ファイルが用いられます。 詳細については以下のドキュメントを参照してください。