【问题标题】:Windows Environment Variable Expansion: Admin vs Non-AdminWindows 环境变量扩展:管理员与非管理员
【发布时间】:2017-02-21 20:48:13
【问题描述】:

我有一个 C# 应用程序,它在运行时会设置一些环境变量。 这些环境变量需要在系统范围内设置。

我使用这段代码来实际做设置。

    public static void SetEnvironmentVariable(string _keyName, string _value, RegistryValueKind _type)
    {
        using (RegistryKey reg = Registry.LocalMachine.OpenSubKey(@"SYSTEM\CurrentControlSet\Control\Session Manager\Environment", true))
        {
            if (reg != null)
            {
                reg.SetValue(_keyName, _value, _type);
            }
            else
            {
                string x =
                    string.Format(
                        "Could find registry key that hosts Environment Variables: SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment");
                App.AppLogger.Error(x);
                throw new Exception(x);
            }
        }
    }

此代码有效,但我注意到一些奇怪的行为。 运行我的应用程序和此代码后,我立即以普通用户身份运行 cmd 并使用“set”命令查看环境。 它没有显示任何变化。

然后我以管理员身份运行 cmd 提示符并运行 set。它显示了变化。不仅如此,它还显示了完全扩展的变量。其中ALLFOO=Foo,PATH=C:\Windows\System32;%ALLFOO%;,设置命令显示PATH=C:\Windows\System32;Foo;。

然后我注销并重新登录。然后我以普通用户身份运行 cmd 。 我输入 set ,它显示了新的环境变量,但没有展开。 它显示 PATH=C:\Windows\System32;%ALLFOO%; (由于某种原因,扩展 %SYSTEMROOT% 似乎没有问题。)

我知道注销并重新启动会导致启动的新 Explorer.exe 为普通用户的 cmd.exe 获取新的环境变量,但我不明白为什么它们没有被扩展。

为什么以管理员身份运行 cmd 会显示完全展开的环境变量,而以普通用户身份运行 cmd 和设置却不会?

在 C# 程序中设置环境变量时,我使用 RegistryValueKind.ExpandString 枚举。

编辑: 我知道系统变量的声明时间到扩展时间问题的顺序,并编辑了问题示例以反映这一点。

【问题讨论】:

    标签: c# windows cmd registry


    【解决方案1】:

    对环境变量的更改是不可见的。您需要将notify 正在运行的进程更改为注册表。

    而且,您应该记住,您在进程中看到的环境(您的cmd 窗口)不是从注册表中读取的,而是从其父进程继承的。您可以发送通知,但有些进程会处理它,有些则不会。

    剩下的问题应该通过环境加载顺序来解释:

    • 在处理环境本身之前,会从注册表中检索一些值。 %systemroot%

      中定义
      HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\SystemRoot
      
    • 系统环境已加载

      • REG_SZ 变量,按字母顺序,先读取
      • REG_EXPAND_SZ,按字母顺序阅读。由于已读取 REG_SZ 值,因此可以扩展它们。如果REG_EXPAND_SZ 变量引用了另一个尚未展开(按字母顺序)的REG_EXPAND_SZ 变量,则此引用无法解析且不会展开。
    • 当用户登录时,处理用户环境。
      • 处理相同的REG_SZ,然后处理REG_EXPAND_SZ 变量。
      • 在用户级别定义的变量会覆盖系统环境的值,但某些变量(例如PATH)的值是串联的。

    这意味着

    • 不同的用户可以并且可能会看到不同的环境

    • 同一用户可以看到不同的环境,具体取决于父进程是什么。使用Win+R并执行cmd与在文件夹中使用Shift+右键并选择“在此处打开命令”是不一样的。父进程不同。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-07-10
      • 1970-01-01
      • 2017-05-10
      • 1970-01-01
      • 2017-08-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多