次のコードを使用して、環境変数を取得および設定しています。
public static string Get( string name, bool ExpandVariables=true ) {
if ( ExpandVariables ) {
return System.Environment.GetEnvironmentVariable( name );
} else {
return (string)Microsoft.Win32.Registry.LocalMachine.OpenSubKey( @"SYSTEM\CurrentControlSet\Control\Session Manager\Environment\" ).GetValue( name, "", Microsoft.Win32.RegistryValueOptions.DoNotExpandEnvironmentNames );
}
}
public static void Set( string name, string value ) {
System.Environment.SetEnvironmentVariable( name, value );
}
私が直面している問題は、プログラムが管理者として実行されている場合でも、環境変数はプログラムが実行されている間だけ持続することです。前のインスタンスで設定した変数に対してGetを実行することで、これを確認しました。
上記の使用例
Set("OPENSSL_CONF", @"c:\openssl\openssl.cfg");
そして取得するには
MessageBox.Show( Get("OPENSSL_CONF") );
プログラムの実行中、Set
を使用した後、値はGet
を使用して問題なく返されます。問題は、環境変数が永続的ではない(システムに設定されている)ことです。
また、高度なプロパティの下に表示されることもありません。
前もって感謝します。
プログラムの実行中、Setを使用した後、Getを使用して値が問題なく返されます。問題は、環境変数が永続的ではない(システムに設定されている)ことです。
これは、使用しているSetEnvironmentVariable
のオーバーロードがprocess変数に格納されているためです。 docs から:
このメソッドを呼び出すことは、ターゲット引数にEnvironmentVariableTarget.Processの値を指定してSetEnvironmentVariable(String、String、EnvironmentVariableTarget)オーバーロードを呼び出すことと同じです。
代わりに EnvironmentVariableTarget.Machine
を指定してオーバーロードを使用する必要があります。
public static void Set(string name, string value)
{
Environment.SetEnvironmentVariable(name, value, EnvironmentVariableTarget.Machine);
}
MSDNによると、使用している方法は、プロセスの実行時に変数を変更するだけです。
ここで説明されているオーバーロードを試してください: https://msdn.Microsoft.com/library/96xafkes%28v=vs.110%29.aspx
レジストリをプログラムで編集することにより、ユーザーPATH変数を永続的に更新する例を次に示します。
// Admin Permission not-required:
// HKCU\Environment\Path
// Admin Permission required:
// HKLM\SYSTEM\CurrentControlSet\Control
// \Session Manager\Environment\Path
public static void UserPathAppend(string path, int verbose=1) {
string oldpath = UserPathGet();
List<string> newpathlist = oldpath.Split(';').ToList();
newpathlist.Add(path);
string newpath = String.Join(";", newpathlist.ToArray());
UserPathSet(newpath);
UpdateEnvPath();
if (verbose!=0) {
System.Windows.MessageBox.Show(
"PATH APPEND:\n\n"
+ path + "\n\n"
+ "OLD HKCU PATH:\n\n"
+ oldpath + "\n\n"
+ "NEW HKCU PATH:\n\n"
+ newpath + "\n\n"
+ "REGISTRY KEY MODIFIED:\n\n"
+ "HKCU\\Environment\\Path\n\n"
+ "NOTE:\n\n"
+ "'Command Path' is a concat of 'HKLM Path' & 'HKCU Path'.\n",
"Updated Current User Path Environment Variable"
);
}
}
public static void UserPathPrepend(string path, int verbose=1) {
string oldpath = UserPathGet();
List<string> newpathlist = oldpath.Split(';').ToList();
newpathlist.Insert(0, path);
string newpath = String.Join(";", newpathlist.ToArray());
UserPathSet(newpath);
UpdateEnvPath();
if (verbose != 0) {
System.Windows.MessageBox.Show(
"PATH PREPEND:\n\n"
+ path + "\n\n"
+ "OLD HKCU PATH:\n\n"
+ oldpath + "\n\n"
+ "NEW HKCU PATH:\n\n"
+ newpath + "\n\n"
+ "REGISTRY KEY MODIFIED:\n\n"
+ "HKCU\\Environment\\Path\n\n"
+ "NOTE:\n\n"
+ "'Command Path' is a concat of 'HKLM Path' & 'HKCU Path'.\n",
"Updated Current User Path Environment Variable"
);
}
}
public static string UserPathGet()
{
// Reads Registry Path "HKCU\Environment\Path"
string subKey = "Environment";
Microsoft.Win32.RegistryKey sk = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(subKey);
if (sk == null)
return null;
else
return sk.GetValue("Path").ToString();
}
public static void UserPathSet(string newpath)
{
// Writes Registry Path "HKCU\Environment\Path"
string subKey = "Environment";
Microsoft.Win32.RegistryKey sk1 = Microsoft.Win32.Registry.CurrentUser.CreateSubKey(subKey);
sk1.SetValue("Path", newpath);
}
//===========================================================
// Private: This part required if you don't want to logout
// and login again to see Path Variable update
//===========================================================
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
private static extern IntPtr SendMessageTimeout(IntPtr hWnd,
uint Msg, UIntPtr wParam, string lParam,
SendMessageTimeoutFlags fuFlags,
uint uTimeout, out UIntPtr lpdwResult);
private enum SendMessageTimeoutFlags : uint
{
SMTO_NORMAL = 0x0, SMTO_BLOCK = 0x1,
SMTO_ABORTIFHUNG = 0x2, SMTO_NOTIMEOUTIFNOTHUNG = 0x8
}
private static void UpdateEnvPath() {
// SEE: https://support.Microsoft.com/en-us/help/104011/how-to-propagate-environment-variables-to-the-system
// Need to send WM_SETTINGCHANGE Message to
// propagage changes to Path env from registry
IntPtr HWND_BROADCAST = (IntPtr)0xffff;
const UInt32 WM_SETTINGCHANGE = 0x001A;
UIntPtr result;
IntPtr settingResult
= SendMessageTimeout(HWND_BROADCAST,
WM_SETTINGCHANGE, (UIntPtr)0,
"Environment",
SendMessageTimeoutFlags.SMTO_ABORTIFHUNG,
5000, out result);
}