宇宙仮面の
C# Programming

 

Image環境変数

開発環境: Visual Studio 2003 

1.目次

  1. 目次
  2. 目的
  3. 参考書
  4. 環境変数を扱う4つの方法
  5. System.Environmentを使用する方法
  6. レジストリを使用する方法
  7. Platform SDK を使用する方法
  8. WMI を使用する方法
  9. 改訂履歴
  10. テスト用ソースコード

2.目的

.NET-C# eGroup で話題になったので、ちょっとまとめてみました。
環境変数を扱う方法には、4つあります。それぞれのメリット・デメリットを説明します。

3.参考書

  1. MSDN System.Environment
  2. MSDN SetEnvironment Platform SDK
  3. MSDN WMI/Win32_Environment
  4. C# プログラミング: InterOp
  5. C# プログラミング: WMI

4.環境変数を扱う4つの方法

環境変数を扱う4つの方法は次のとおりです。
用途に応じて使い分けるしかないですね。

方法 メリット デメリット
System.Environment を使用する方法一番簡単環境変数をセットするメソッドが用意されていない。

対象OS が限定。
Windows 98, Windows NT 4.0以降。
Microsoft.Win32.Registry を使用する方法簡単レジストリを直接操作するので、危険。

対象OS が限定。
Windows 98, Windows NT 4.0以降。
Platform SDK を使用する方法現在のプロセスのみに値をセットでき、システム環境変数や他のプロセスの環境変数へ影響を及ぼさない。

対象OSが広い。
Windows NT 3.1 以降
Windows 95/98:Windows 95 以降
他のプロセスの環境変数や、コントロールパネルの環境変数の値を変更できない。

対象OSが広い。
Windows NT 3.1 以降
Windows 95/98:Windows 95 以降

ちょっと面倒。

細かい設定ができない。
WMIを使用する方法詳細な情報が取れる。

値もセットできる。

リモートPCにも適用できる。
面倒。WMIを正しく理解する必要あり。

95/98/Me に使えない。
対象OS :  Windows NT 4.0 SP4 or later

5.System.Environmentを使用する方法


System.Environment を使って、1つの環境変数を得る。
string usrName = System.Environment.GetEnvironmentVariable("USERNAME");
System.Environment を使って、すべての環境変数を得る。
IDictionary idict = System.Environment.GetEnvironmentVariables();
IDictionaryEnumerator denum = idict.GetEnumerator();
while( denum.MoveNext() )
{
Console.WriteLine("{0} = {1}", denum.Key, denum.Value);
}

6.レジストリを使用する方法

レジストリを使って、システム環境変数を得る。
using Microsoft.Win32;

RegistryKey regKey = Registry.LocalMachine.OpenSubKey(@"System\CurrentControlSet\Control\Session Manager\Environment");
string [] names = regKey.GetValueNames();
foreach(string name in names)
{
Console.WriteLine(name + " : " + regKey.GetValue(name));
}

1つだけとるなら、object val = GetValue(name);
レジストリを使って、ユーザ環境変数を得る。

using Microsoft.Win32;

RegistryKey regKey = Registry.CurrentUser.OpenSubKey("Environment");
string [] names = regKey.GetValueNames();
foreach(string name in names)
{
Console.WriteLine(name + " : " + regKey.GetValue(name));
}

1つだけとるなら、object val = GetValue(name);

注意: 直接レジストリの操作をします。下手すると、システムに致命的な結果をもたらします。試す場合は、自己責任でやってね!

 

レジストリを使って、システム環境変数をセットする。
using Microsoft.Win32;

RegistryKey regKey = Registry.LocalMachine.CreateSubKey(@"System\CurrentControlSet\Control\Session Manager\Environment");
regKey.SetValue(name, val);
レジストリを使って、ユーザ環境変数をセットする。
using Microsoft.Win32;

RegistryKey regKey = Registry.CurrentUser.CreateSubKey("Environment");
regKey.SetValue(name, val);

7.Platform SDK を使用する方法

Kernel32.dll の SetEnvironmentVariable(), GetEnvironmentVariable() のプラットフォームSDK 呼び出しを行います。

System.Environment を使って、1つの環境変数をセットする。
注意: 現在のプロセスの環境変数を変更するだけで、コントロールパネルの環境変数を永続的に修正するものではありません。

using System.Runtime.InteropServices;
...
//BOOL SetEnvironmentVariable(
// LPCTSTR lpName, // 環境変数の名前
// LPCTSTR lpValue // 環境変数の新しい値
// );
[DllImport("Kernel32.dll")]
static extern bool SetEnvironmentVariable(string name, string val);

bool result = SetEnvironmentVariable("Hello", "World");
System.Environment を使って、すべての環境変数を得る。
using System.Text;
using System.Runtime.InteropServices;
...
// DWORD GetEnvironmentVariable(
// LPCTSTR lpName, // 環境変数の名前
// LPTSTR lpBuffer, // 変数の値が格納されるバッファ
// DWORD nSize // バッファのサイズ
// );
[DllImport("Kernel32.dll")]
static extern uint GetEnvironmentVariable(string name, StringBuilder sb, uint sbLen);

string query = "test";
StringBuilder sb = new StringBuilder(256);
uint result = GetEnvironmentVariable(query, sb, (uint)sb.Capacity);


8.WMI を使用する方法

WMI( Windows Management Instrumentation) を使用します。

WMI  を使って、1つの環境変数を得る。
using System.Runtime.InteropServices;
...
ManagementObjectSearcher query1 =
new ManagementObjectSearcher("SELECT * FROM Win32_Environment WHERE NAME = '" + name +"'") ;
ManagementObjectCollection queryCollection1 = query1.Get();

foreach( ManagementObject mo in queryCollection1 )
{
Console.WriteLine("Name:" + mo["Name"]);
Console.WriteLine("VariableValue:" + mo["VariableValue"]);
Console.WriteLine("Caption:" + mo["Caption"]);
Console.WriteLine("Description:" + mo["Description"]);
Console.WriteLine("InstallDate:" + mo["InstallDate"]);
Console.WriteLine("Status:" + mo["Status"].ToString());
Console.WriteLine("SystemVariable:" + mo["SystemVariable"]);
Console.WriteLine("UserName:" + mo["UserName"]);
}
WMI  を使って、すべての環境変数を得る。
using System.Runtime.InteropServices;
...
ManagementObjectSearcher query1 =
new ManagementObjectSearcher("SELECT * FROM Win32_Environment") ;
ManagementObjectCollection queryCollection1 = query1.Get();
foreach( ManagementObject mo in queryCollection1 )
{
Console.WriteLine("Name:" + mo["Name"]);
Console.WriteLine("VariableValue:" + mo["VariableValue"]);
Console.WriteLine("Caption:" + mo["Caption"]);
Console.WriteLine("Description:" + mo["Description"]);
Console.WriteLine("InstallDate:" + mo["InstallDate"]);
Console.WriteLine("Status:" + mo["Status"].ToString());
Console.WriteLine("SystemVariable:" + mo["SystemVariable"]);
Console.WriteLine("UserName:" + mo["UserName"]);
}
WMI  を使って、環境変数をセットする。
using System.Runtime.InteropServices;
...
// TMP 環境変数の名前と値を変えて、別の環境変数として Put() する。
// このため、美しくないけど、TMP 環境変数があることを前提としています。
// 間違って、TMP を書き換えないように注意!
Console.WriteLine("----------- Set Environment Variable -------------");
ManagementObjectSearcher query1 =
new ManagementObjectSearcher("SELECT * FROM Win32_Environment WHERE NAME = 'TMP'") ;
ManagementObjectCollection queryCollection1 = query1.Get();
foreach( ManagementObject mo in queryCollection1 )
{
mo["Name"] = name;
mo["VariableValue"] = val;
// UserName は "<SYSTEM>"か"<DEFAULT>"
// マニュアルには書いていないけど、
// それ以外に"HOST\USER"か"DOMAIN\USER"
mo["UserName"] = @"UCHUKAMEN\Uchukamen";
mo["SystemVariable"] = systemVariable;
mo.Put();
Console.WriteLine("----------- Done -------------");
break;
}

9.改訂履歴

2002/3/2   初版作成。
2003/6/7  全面改訂。
2003/6/11 レジストリを追加。

10.テスト用ソースコード

注意: 直接レジストリの操作をします。

下手すると、システムに致命的な結果をもたらします。

試す場合は、自己責任でやってね!

テスト用コード
using System;
using System.Text;
using System.Collections;
using System.Management;
using System.Runtime.InteropServices;
using Microsoft.Win32;

namespace EnvironmentVariables
{
        /// <summary>
        /// Class1 の概要の説明です。
        /// </summary>
        class Class1
        {
                /// <summary>
                /// アプリケーションのメイン エントリ ポイントです。
                /// </summary>
        [STAThread]
        static void Main(string[] args)
        {
            try
            {
                // System.Environment を使って、1つの環境変数を得る。
                SystemEnvironment();

                // Platform SDK を使う方法
                PlatformSDKSet();
                PlatformSDKGet();

                // WMI を使う方法
                WMIPrintEnv("Path");
                WMIEnumEnv();
                WMISetEnv("TestWMI", "WMI", false);
                WMIPrintEnv("TestWMI");

                // レジストリを使う方法
                RegSetEnv("TestReg", "Hello World System", true);
                RegSetEnv("TestReg", "Hello World User", false);
                RegPrintEnv(true);
                RegPrintEnv(false);
            }
            catch (Exception exc)
            {
                Console.WriteLine("失敗しました。" + exc.Message); 
            }
        }

        
        // ------------------------ System.Environment ------------------------------
        static void SystemEnvironment()
        {
            // System.Environment を使って、1つの環境変数を得る。
            string usrName = System.Environment.GetEnvironmentVariable("USERNAME");
            Console.WriteLine("USERNAME = " + usrName);
            Console.WriteLine("--------------------------");
            // System.Environment を使って、すべての環境変数を得る。
            IDictionary idict = System.Environment.GetEnvironmentVariables();
            IDictionaryEnumerator denum = idict.GetEnumerator();
            while( denum.MoveNext() )
            {
                Console.WriteLine("{0} = {1}", denum.Key, denum.Value);
            }

            Console.ReadLine();
        }

        
        // ------------------------ PlatformSDK ------------------------------

        //BOOL SetEnvironmentVariable(
        //    LPCTSTR lpName,  // 環境変数の名前
        //    LPCTSTR lpValue  // 環境変数の新しい値
        //    );
        [DllImport("Kernel32.dll")]
        static extern bool SetEnvironmentVariable(string name, string val);

        static void PlatformSDKSet()
        {
            bool result = SetEnvironmentVariable("TestPlatformSDK", "Hello World");
            
            Console.WriteLine("SetEnvironmentVariable result = {0}", result.ToString());
            
            Console.ReadLine();
        }

        // DWORD GetEnvironmentVariable(
        //    LPCTSTR lpName,  // 環境変数の名前
        //    LPTSTR lpBuffer, // 変数の値が格納されるバッファ
        //    DWORD nSize      // バッファのサイズ
        //    );
        [DllImport("Kernel32.dll")]
        static extern uint GetEnvironmentVariable(string name, StringBuilder sb, uint sbLen);

        static void PlatformSDKGet()
        {
            string query = "TestPlatformSDK";
            StringBuilder sb = new StringBuilder(256);
            uint result = GetEnvironmentVariable(query, sb, (uint)sb.Capacity);
            
            Console.WriteLine("GetEnvironmentVariable result = {0}: {1} = {2}", 
                result.ToString(), query, sb.ToString());
            
            Console.ReadLine();
        }

        // ------------------------ WMI ------------------------------
        static void WMIPrintEnv(string name)
        {
            ManagementObjectSearcher query1 = 
                new ManagementObjectSearcher("SELECT * FROM Win32_Environment WHERE NAME = '" + name +"'") ;
            ManagementObjectCollection queryCollection1 = query1.Get();
            foreach( ManagementObject mo in queryCollection1 ) 
            {
                Console.WriteLine("--------------------------");
                Console.WriteLine("Name:" + mo["Name"]);
                Console.WriteLine("VariableValue:" + mo["VariableValue"]);
                Console.WriteLine("Caption:" + mo["Caption"]); 
                Console.WriteLine("Description:" + mo["Description"]); 
                Console.WriteLine("InstallDate:" + mo["InstallDate"]); 
                Console.WriteLine("Status:" + mo["Status"].ToString()); 
                Console.WriteLine("SystemVariable:" + mo["SystemVariable"]); 
                Console.WriteLine("UserName:" + mo["UserName"]); 
            }
            Console.ReadLine();
            
        }

        static void WMIEnumEnv()
        {
            ManagementObjectSearcher query1 = 
                new ManagementObjectSearcher("SELECT * FROM Win32_Environment") ;
            ManagementObjectCollection queryCollection1 = query1.Get();
            foreach( ManagementObject mo in queryCollection1 ) 
            {
                Console.WriteLine("--------------------------");
                Console.WriteLine("Name:" + mo["Name"]);
                Console.WriteLine("VariableValue:" + mo["VariableValue"]);
                Console.WriteLine("Caption:" + mo["Caption"]); 
                Console.WriteLine("Description:" + mo["Description"]); 
                Console.WriteLine("InstallDate:" + mo["InstallDate"]); 
                Console.WriteLine("Status:" + mo["Status"].ToString()); 
                Console.WriteLine("SystemVariable:" + mo["SystemVariable"]); 
                Console.WriteLine("UserName:" + mo["UserName"]); 
            }
            Console.ReadLine();
        }

        static void WMISetEnv(string name, string val, bool systemVariable)
        {
            // TMP 環境変数の名前と値を変えて、別の環境変数として Put() する。
            // このため、美しくないけど、TMP 環境変数があることを前提としています。
            // 間違って、TMP を書き換えないように注意!
            Console.WriteLine("----------- Set Environment Variable -------------");
            ManagementObjectSearcher query1 = 
                new ManagementObjectSearcher("SELECT * FROM Win32_Environment WHERE NAME = 'TMP'") ;
            ManagementObjectCollection queryCollection1 = query1.Get();
            foreach( ManagementObject mo in queryCollection1 ) 
            {
                mo["Name"] = name;
                mo["VariableValue"] = val;
                // UserName は "<SYSTEM>"か"<DEFAULT>"
                // マニュアルには書いていないけど、
                // それ以外に"HOST\USER"か"DOMAIN\USER"
                mo["UserName"] = @"UCHUKAMEN\Uchukamen";
                mo["SystemVariable"] = systemVariable;
                mo.Put();
                Console.WriteLine("----------- Done -------------");
                break;
            }
            Console.ReadLine();
        }

        static void RegPrintEnv(bool systemVariable)
        {
            Console.WriteLine("------------ RegPrintEnv --------------");
            string [] names = null;
            RegistryKey regKey = null;
            if (systemVariable)
            {
                regKey = Registry.LocalMachine.OpenSubKey(@"System\CurrentControlSet\Control\Session Manager\Environment");
                names = regKey.GetValueNames();
            }
            else
            {
                regKey = Registry.CurrentUser.OpenSubKey("Environment");
                names = regKey.GetValueNames();
            }
            foreach(string name in names)
            {
                Console.WriteLine(name + " : " + regKey.GetValue(name));
            }
            Console.ReadLine();
        }

        static void RegSetEnv(string name, string val, bool systemVariable)
        {
            Console.WriteLine("------------ RegSetEnv --------------");
            RegistryKey regKey = null;
            if (systemVariable)
            {
                regKey = Registry.LocalMachine.CreateSubKey(@"System\CurrentControlSet\Control\Session Manager\Environment");
            }
            else
            {
                regKey = Registry.CurrentUser.CreateSubKey("Environment");
            }
            regKey.SetValue(name, val);
            Console.ReadLine();
        }
        }
}