如何在c#中永久设置环境变量
本文关键字:设置 环境变量 | 更新日期: 2023-09-27 17:54:24
我使用下面的代码来获取和设置环境变量。
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
的过载存储在进程变量中。来自文档:
调用此方法相当于调用setenenvironmentvariable (String, String, EnvironmentVariableTarget)重载一个值为的EnvironmentVariableTarget。进程/blockquote>
您需要使用指定
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
这类问题已经被问过很多次了,点击以下链接获取更多信息:
设置环境变量- 1
设置环境变量- 2
设置环境变量-教程
下面是一个通过编程编辑注册表永久更新User 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);
}