获取PATH变量的GetEnvironmentVariable()和SetEnvironmentVariable()

本文关键字:SetEnvironmentVariable GetEnvironmentVariable PATH 变量 获取 | 更新日期: 2023-09-27 18:06:01

我想用一个c#程序扩展当前的PATH变量。这里我有几个问题:

  1. 使用GetEnvironmentVariable("PATH", EnvironmentVariableTarget.Machine)替换占位符(即'%SystemRoot%'system32'被当前路径'C:'Windows'system32'替换)。更新PATH变量,我不想用路径替换占位符

  2. SetEnvironmentVariable之后,没有程序可以从命令框中打开(即命令框中的calc.exe不起作用)。我使用以下代码:

String oldPath = Environment.GetEnvironmentVariable("PATH", EnvironmentVariableTarget.Machine);
Environment.SetEnvironmentVariable("PATH", oldPath + ";%MYDIR%", EnvironmentVariableTarget.Machine);

在编辑和改变PATH变量后,一切都可以再次工作。

获取PATH变量的GetEnvironmentVariable()和SetEnvironmentVariable()

您可以使用注册表读取和更新:

string keyName = @"SYSTEM'CurrentControlSet'Control'Session Manager'Environment";
//get non-expanded PATH environment variable            
string oldPath = (string)Registry.LocalMachine.CreateSubKey(keyName).GetValue("Path", "", RegistryValueOptions.DoNotExpandEnvironmentNames);
//set the path as an an expandable string
Registry.LocalMachine.CreateSubKey(keyName).SetValue("Path", oldPath + ";%MYDIR%",    RegistryValueKind.ExpandString);

您可以使用WMI检索原始值(但不确定是否更新它们):

ManagementObjectSearcher searcher = new ManagementObjectSearcher("select * from Win32_Environment WHERE Name = 'PATH'");
foreach (ManagementBaseObject managementBaseObject in searcher.Get())
     Console.WriteLine(managementBaseObject["VariableValue"]);

检查MSDN上的WMI引用

你可以试试这个组合。它从注册表中获取Path变量,并将"NewPathEntry"添加到Path中,如果还没有的话。

static void Main(string[] args)
    {
        string NewPathEntry = @"%temp%'data";
        string NewPath = "";
        bool MustUpdate = true;
        string RegKeyName = @"SYSTEM'CurrentControlSet'Control'Session Manager'Environment";
        string path = (string)Microsoft.Win32.Registry.LocalMachine.OpenSubKey(RegKeyName).GetValue
            ("Path", "", Microsoft.Win32.RegistryValueOptions.DoNotExpandEnvironmentNames);
        string[] paths = path.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
        foreach (string subPath in paths)
        {
            NewPath += subPath + ";";
            if (subPath.ToLower() == NewPathEntry.ToLower())
            {
                MustUpdate = false;
            }
        }
        if (MustUpdate == true)
        {
            Environment.SetEnvironmentVariable("Path", NewPath + NewPathEntry, EnvironmentVariableTarget.Machine);
        }
    }

您可以查看注册表…

string keyName = @"HKEY_LOCAL_MACHINE'SYSTEM'CurrentControlSet'Control'Session Manager'Environment";
//get raw PATH environment variable
string path = (string)Registry.GetValue(keyName, "Path", "");
//... Make some changes
//update raw PATH environment variable
Registry.SetValue(keyName, "Path", path);

在应用程序上工作时,我们必须有一个从用户定义文件夹中使用Oracle instantclient的选项。为了使用即时客户端,我们必须修改环境路径变量,并在调用任何Oracle相关功能之前添加这个文件夹。这是我们使用的方法:

    /// <summary>
    /// Adds an environment path segments (the PATH varialbe).
    /// </summary>
    /// <param name="pathSegment">The path segment.</param>
    public static void AddPathSegments(string pathSegment)
    {
        LogHelper.Log(LogType.Dbg, "EnvironmentHelper.AddPathSegments", "Adding path segment: {0}", pathSegment);
        string allPaths = Environment.GetEnvironmentVariable("PATH", EnvironmentVariableTarget.Process);
        if (allPaths != null)
            allPaths = pathSegment + "; " + allPaths;
        else
            allPaths = pathSegment;
        Environment.SetEnvironmentVariable("PATH", allPaths, EnvironmentVariableTarget.Process);
    }

请注意,这必须在任何其他内容之前调用,可能作为Main文件的第一行(不确定是否适用于控制台应用程序)。

使用Registry.GetValue将扩展占位符,因此我建议使用Registry.LocalMachine.OpenSubKey,然后从子键获取值,并将选项设置为不扩展环境变量。一旦您按照自己的喜好操作了路径,就可以使用注册表再次设置该值。这将防止Windows"忘记"你的路径,正如你在问题的第二部分提到的。

const string pathKeyName = @"SYSTEM'CurrentControlSet'Control'Session Manager'Environment";
var pathKey = Registry.LocalMachine.OpenSubKey(pathKeyName);
var path = (string)pathKey.GetValue("PATH", "", RegistryValueOptions.DoNotExpandEnvironmentNames);
// Manipulate path here, storing in path
Registry.SetValue(String.Concat(@"HKEY_LOCAL_MACHINE'", pathKeyName), "PATH", path);