【问题标题】:GetEnvironmentVariable() and SetEnvironmentVariable() for PATH VariablePATH 变量的 GetEnvironmentVariable() 和 SetEnvironmentVariable()
【发布时间】:2011-10-30 14:43:42
【问题描述】:

我想用 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);

在使用 Windows 编辑和更改 PATH 变量后,一切都会再次运行。 (我的东西需要改变,否则不会被覆盖)

【问题讨论】:

  • 为什么不为 PATH 使用占位符? SetEnvironmentVariable("PATH", "%PATH%;%MYDIR%", EnvironmentVariableTarget.Machine);
  • 那么PATH变量是:'%PATH%;%MYDIR%'
  • 啊,那么对不起。我认为这可能会像在命令行中使用SET PATH=%PATH% 那样工作。除了用占位符替换字符串之外,我不确定该建议什么。
  • 使用像SET PATH=%PATH%;%MYDIR% 这样的命令行对我也不起作用...

标签: c# .net windows environment-variables


【解决方案1】:

使用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);

【讨论】:

    【解决方案2】:

    你可以试试这个组合。它从注册表中获取 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);
            }
        }
    

    【讨论】:

      【解决方案3】:

      在处理应用程序时,我们必须从用户定义的文件夹中选择使用 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);
          }
      

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

      【讨论】:

        【解决方案4】:

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

        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);
        

        【讨论】:

          【解决方案5】:

          你可以通过注册表...

          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);
          

          【讨论】:

            【解决方案6】:

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

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

            在 MSDN 上查看 WMI Reference

            【讨论】:

              猜你喜欢
              • 2020-02-01
              • 2022-10-14
              • 1970-01-01
              • 2013-04-23
              • 1970-01-01
              • 1970-01-01
              • 2012-09-05
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多