Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在C#中设置系统环境变量?_C#_.net_Environment Variables - Fatal编程技术网

如何在C#中设置系统环境变量?

如何在C#中设置系统环境变量?,c#,.net,environment-variables,C#,.net,Environment Variables,我试图在应用程序中设置一个系统环境变量,但得到了一个SecurityException。我测试了在谷歌找到的所有东西,但没有成功。 以下是我的代码(请注意,我是电脑管理员,以管理员身份运行VS2012): 尝试1 new EnvironmentPermission(EnvironmentPermissionAccess.Write, "TEST1").Demand(); Environment.SetEnvironmentVariable("TEST1", "MyTest", Environme

我试图在应用程序中设置一个系统环境变量,但得到了一个
SecurityException
。我测试了在谷歌找到的所有东西,但没有成功。 以下是我的代码(请注意,我是电脑管理员,以管理员身份运行VS2012):

尝试1

new EnvironmentPermission(EnvironmentPermissionAccess.Write, "TEST1").Demand();
Environment.SetEnvironmentVariable("TEST1", "MyTest", EnvironmentVariableTarget.Machine);
尝试2

new EnvironmentPermission(EnvironmentPermissionAccess.Write, "TEST1").Demand();

using (var envKey = Registry.LocalMachine.OpenSubKey(@"SYSTEM\CurrentControlSet\Control\Session Manager\Environment", true))
{

  Contract.Assert(envKey != null, @"HKLM\System\CurrentControlSet\Control\Session Manager\Environment is missing!");
  envKey.SetValue("TEST1", "TestValue");
}
尝试3次 我还试着穿上我的衣服

你还有其他建议吗?

告诉你怎么做

调用
SetEnvironmentVariable
对系统环境变量没有影响。要以编程方式添加或修改系统环境变量,请将它们添加到
HKEY\U LOCAL\U MACHINE\system\CurrentControlSet\Control\Session Manager\environment
注册表项中,然后将
WM\U SETTINGCHANGE
消息与
lParam
设置为字符串
“environment”
。这允许应用程序(如shell)获取您的更新

因此,您需要写入已尝试写入的注册表设置。然后播放
WM_SETTINGCHANGE
消息,如上所述。您需要以提升的权限运行才能成功

一些示例代码:

using Microsoft.Win32;
using System;
using System.Diagnostics.Contracts;
using System.Runtime.InteropServices;

namespace ConsoleApplication1
{
    class Program
    {
        const int HWND_BROADCAST = 0xffff;
        const uint WM_SETTINGCHANGE = 0x001a;

        [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        static extern bool SendNotifyMessage(IntPtr hWnd, uint Msg, 
            UIntPtr wParam, string lParam);

        static void Main(string[] args)
        {
            using (var envKey = Registry.LocalMachine.OpenSubKey(
                @"SYSTEM\CurrentControlSet\Control\Session Manager\Environment",
                true))
            {
                Contract.Assert(envKey != null, @"registry key is missing!");
                envKey.SetValue("TEST1", "TestValue");
                SendNotifyMessage((IntPtr)HWND_BROADCAST, WM_SETTINGCHANGE,
                    (UIntPtr)0, "Environment");
            }
        }
    }
}
然而,尽管这段代码确实有效,.net framework提供了更简单地执行相同任务的功能

Environment.SetEnvironmentVariable("TEST1", "TestValue", 
    EnvironmentVariableTarget.Machine);
三个参数
Environment.SetEnvironmentVariable
重载的

如果目标是EnvironmentVariableTarget.Machine,则环境变量存储在本地计算机注册表的HKEY_LOCAL_Machine\SYSTEM\ControlSet001\Control\Session Manager\environment项中。它还会复制到文件资源管理器的所有实例。然后,从文件资源管理器启动的任何新进程都会继承环境变量

如果目标是用户或计算机,则通过Windows WM_SETTINGCHANGE消息通知其他应用程序设置操作


你不能只是去获得许可。你需要被提升。这需要在进程启动时完成。正如我所说的,调用
OpenSubKey
函数也会以异常结束,尽管该键是可用的。正如我所说的,您需要运行这个函数。当你这样做的时候,你会发现它是有效的。我确实测试过这个代码,你知道!啊,真管用!非常感谢你。是否有命令或参数来确认此UAC警告?如果有这样的事情,将使UAC变得毫无意义,不是吗。如果你想做管理员任务,你需要成为管理员。值得注意的是,即使是在最新的4.6.2版本中,.Net Framework中的setEnvironmentVariablel()函数也存在一个错误,即不检查您是否正在设置路径变量--它对它们的处理都是一样的,它将静默地将PATH的注册表项类型从REG_EXPAND_SZ更改为REG_SZ,从而停止在PATH中使用变量扩展的功能。不用说,许多程序(和计算机用户)依赖于路径扩展。