2016-03-26T17:04:00の更新内容

programming/netfx/environment_variables/index.wiki.txt

current previous
1,801 0,0
+
${smdncms:title,環境変数}
+
${smdncms:keywords,プロセス,環境変数}
+
${smdncms:document_versions,codelang=cs,codelang=vb}
+

          
+
&msdn(netfx,type,System.Environment){System.Environment};クラスの&msdn(netfx,member,System.Environment.GetEnvironmentVariable){GetEnvironmentVariableメソッド};・&msdn(netfx,member,System.Environment.SetEnvironmentVariable){SetEnvironmentVariableメソッド};を用いることにより、プロセスの[[環境変数の取得>#Environment.GetEnvironmentVariable]]・[[設定>#Environment.SetEnvironmentVariable]]をすることができます。 子プロセスを起動する場合には、&msdn(netfx,member,System.Diagnostics.ProcessStartInfo.EnvironmentVariables){ProcessStartInfo.EnvironmentVariablesプロパティ};を用いることにより[[環境変数を追加・削除・変更して子プロセスを起動する>#ProcessStartInfo.EnvironmentVariables]]ことができます。
+

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

          
+
#relevantdocs
+

          
+
-[[programming/netfx/process]]
+
-[[programming/netfx/environment]]
+
--[[programming/netfx/environment/0_platform]]
+
--[[programming/netfx/environment/1_process]]
+
-[[programming/netfx/locale]]
+
--[[programming/netfx/locale/0_abstract]]
+
-[[programming/netfx/filesystem/0_path]]
+
-[[programming/netfx/tips/check_ngchar]]
+

          
+
#relevantdocs-end
+

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

          
+
#tabpage(codelang=cs,container-title=Environment.GetEnvironmentVariableメソッドを使って特定の環境変数を取得する)
+
#code{{
+
using System;
+

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

          
+
    // 環境変数 'Path' を取得・表示 (Windows上では大文字小文字の違いは無視される)
+
    Console.WriteLine("Path={0}", Environment.GetEnvironmentVariable("Path"));
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
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
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果例(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
+
}}
+

          
+
#prompt(実行結果例(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=
+
}}
+

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

          
+
**すべての環境変数の取得 (Environment.GetEnvironmentVariables) [#Environment.GetEnvironmentVariables]
+
&msdn(netfx,member,System.Environment.GetEnvironmentVariables){Environment.GetEnvironmentVariablesメソッド};を使うと、現在のプロセスの環境変数すべてを取得できます。 このメソッドは環境変数の名前をエントリの''キー''、環境変数の値をエントリの''値''とする[[IDictionary (ディクショナリ)>programming/netfx/collections/0_abstract]]を返します。
+

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

          
+
#tabpage(codelang=cs,container-title=Environment.GetEnvironmentVariablesメソッドを使ってすべての環境変数を取得する)
+
#code{{
+
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);
+
    }
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
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
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果例(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
+
  :
+
  :
+
(以下略)
+
}}
+

          
+
#prompt(実行結果例(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
+
  :
+
  :
+
(以下略)
+
}}
+

          
+
#remarks
+
IDictionaryの列挙、DictionaryEntry構造体については[[programming/netfx/collections_nongeneric/hashtable#enumeration]]を参照してください。
+
#remarks-end
+

          
+

          
+

          
+

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

          
+
#tabpage(codelang=cs,container-title=Dictionaryを使って環境変数名の大文字小文字の違いを無視して扱う)
+
#code{{
+
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"]);
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
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
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果例(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
+
}}
+

          
+
#prompt(実行結果例(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
+
}}
+

          
+
#remarks
+
Dictionaryと大文字小文字の違いの無視については[[programming/netfx/collections/2_generic_2_dictionary#create_caseinsensitive_dictionary]]、StringComparerについては[[programming/netfx/string/2_2_compareoptions]]で詳しく解説しています。
+
#remarks-end
+

          
+

          
+

          
+
*環境変数の追加・変更・削除 (Environment.SetEnvironmentVariable) [#Environment.SetEnvironmentVariable]
+
環境変数を追加・変更・削除するには&msdn(netfx,member,System.Environment.SetEnvironmentVariable){Environment.SetEnvironmentVariableメソッド};を使うことができます。
+

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

          
+
#tabpage(codelang=cs,container-title=Environment.SetEnvironmentVariableを使ってプロセスの環境変数を追加・変更・削除する)
+
#code{{
+
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);
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
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
+
}}
+
#tabpage-end
+

          
+
**環境変数の設定・取得の対象 (EnvironmentVariableTarget) [#EnvironmentVariableTarget]
+
Environment.SetEnvironmentVariableメソッドでは、変更する環境変数の対象を指定する&msdn(netfx,type,System.EnvironmentVariableTarget){EnvironmentVariableTarget列挙体};を同時に指定することができます。
+

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

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

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

          
+
#remarks
+
&msdn(netfx,member,System.Environment.GetEnvironmentVariable){Environment.GetEnvironmentVariableメソッド};でも同様にEnvironmentVariableTargetを指定して環境変数の取得対象を指定することができます。
+
#remarks-end
+

          
+

          
+

          
+
*環境変数の展開 (Environment.ExpandEnvironmentVariables) [#Environment.ExpandEnvironmentVariables]
+
&msdn(netfx,member,System.Environment.ExpandEnvironmentVariables){Environment.ExpandEnvironmentVariablesメソッド};を使うと、文字列内に含まれる環境変数(``%&var{ENVVAR};%``)を展開して環境変数に設定されている値に置換することができます。 文字列内に複数の環境変数が存在する場合は、そのすべてが置換されます。
+

          
+
#tabpage(codelang=cs,container-title=Environment.ExpandEnvironmentVariablesメソッドを使って文字列内の環境変数を展開する)
+
#code{{
+
using System;
+

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

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

          
+
    Console.WriteLine(filepath);
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
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
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
.\data\file.txt
+
}}
+

          
+
環境変数``PATH``のように複数のパスが指定されている場合は、展開される際にパスが分割されるといったことはなく、指定されている値がそのまま展開されます。 環境変数に設定されているパスを分解して展開したい場合は[[#find_executable_file]]などで掲載しているような方法をとる必要があります。
+

          
+

          
+

          
+

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

          
+
#tabpage(codelang=cs,container-title=環境変数が存在しない場合、Environment.ExpandEnvironmentVariablesメソッドは環境変数を展開しない)
+
#code{{
+
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);
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
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
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
%PATH_DATA%file.txt
+
}}
+

          
+

          
+

          
+

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

          
+
連結された``PATH``を分割するには&msdn(netfx,member,System.String.Split){String.Splitメソッド};([[programming/netfx/string/1_operations#String.Split]])を用いることができます。 Windowsでは``PATH``の区切り文字には"``;``"、Linuxなどでは"``:``"が用いられますが、この区切り文字は&msdn(netfx,member,System.IO.Path.PathSeparator){Path.PathSeparatorフィールド};を参照することで取得でき、これをSplitメソッドに渡すことで実行環境に応じた区切り文字での分割を行うことができます。
+

          
+
#tabpage(codelang=cs,container-title=String.Splitメソッドを使って環境変数PATHを分割する)
+
#code{{
+
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);
+
    }
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
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
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果例(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
+
}}
+

          
+
#prompt(実行結果例(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
+
}}
+

          
+
#remarks
+
Pathクラスを用いてパスをディレクトリ単位で分割したり結合したりする方法については[[programming/netfx/filesystem/0_path]]を参照してください。
+
#remarks-end
+

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

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

          
+
#tabpage(codelang=cs,container-title=PATH環境変数を取得して実行可能ファイルのフルパスを検索する)
+
#code{{
+
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;
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
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
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果例(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
+
}}
+

          
+
#prompt(実行結果例(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``に別のパスを追加する場合も、分割の場合と同様に&msdn(netfx,member,System.IO.Path.PathSeparator){Path.PathSeparatorフィールド};からパス区切り文字を取得して次のようにします。
+

          
+
#tabpage(codelang=cs,container-title=PATH環境変数に別のパスを追加する)
+
#code{{
+
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);
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
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
+
}}
+
#tabpage-end
+

          
+

          
+

          
+

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

          
+
#tabpage(codelang=cs,container-title=PATH環境変数の内容を分割してListに変換し、編集する)
+
#code{{
+
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));
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
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
+
}}
+
#tabpage-end
+

          
+
#remarks
+
環境変数``PATH``にパスを追加して子プロセス(外部アプリケーション)を起動する方法については[[#ProcessStartInfo.EnvironmentVariables]]も参照してください。
+
#remarks-end
+

          
+
#remarks
+
Listクラスの扱い方については[[programming/netfx/collections/2_generic_1_list]]を参照してください。
+
#remarks-end
+

          
+

          
+

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

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

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

          
+
#tabpage(codelang=cs,container-title=環境変数を変更して子プロセスを起動する)
+
#code{{
+
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();
+
    }
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
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
+
}}
+
#tabpage-end
+

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

          
+
#remarks
+
この他、子プロセスの起動や、プロセス起動時のオプションについては[[programming/netfx/process#ProcessStartInfo]]を参照してください。 また、Pathクラスによるパスの分割・結合などの操作については[[programming/netfx/filesystem/0_path]]を参照してください。
+
#remarks-end
+

          
+

          
+

          
+
*環境変数と代替機能
+
**ロケール情報(環境変数LANG・環境変数LC_*)
+
Windowsではコントロールパネルの地域と言語のオプションが用いられるため、環境変数``LANG``の設定は実行時の動作に影響しません。 一方Linux等では環境変数``LANG``の設定に応じた''ロケール''が用いられます。 詳しくは[[programming/netfx/locale/0_abstract#initial_thread_culture]]を参照してください。
+

          
+
また、``LC_ALL``・``LC_NUMERIC``・``LC_TIME``などロケールに関する設定は、.NET Frameworkにおいては''カルチャ''として&msnd(netfx,type,System.Globalization.CultureInfo){CultureInfoクラス};によって扱われ、スレッド毎に設定・変更することができます。 詳しくは[[programming/netfx/locale/0_abstract]]および[[programming/netfx/locale/1_infoes]]を参照してください。
+

          
+

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

          
+
Environment.GetFolderPathメソッドを使った各種ディレクトリのパスの取得については[[programming/netfx/environment/0_platform#SystemAndPlatform_SpecialDirectory]]で解説しています。
+

          
+
一時ディレクトリ(``TMP``・``TEMP``)・一時ファイルについては[[programming/tips/create_temporary_file]]を参照してください。
+

          
+

          
+
**プラットフォーム・実行環境の情報の取得
+
プラットフォームや実行環境など、環境変数からでは取得できない情報の取得に関しては[[programming/netfx/environment/0_platform]]および[[programming/netfx/environment/1_process]]で解説しています。
+

          
+

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

          
+
-&msdn(netfx,id,ms229689){アプリケーション構成ファイル};
+
-&msdn(netfx,id,1fk1t1t0){.NET Framework の構成ファイル スキーマ};
+

          
+

          
+