2013-10-31 117 views
4

我想在我的应用程序中设置一个系统环境变量,但得到一个SecurityException。我测试了我在谷歌找到的所有东西 - 没有成功。 这里是我的代码(注意,我是我的电脑的管理员和运行VS2012为管理员):如何在C#中设置系统环境变量?

尝试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 另外我试图装出我的app with administrator priviliges

您有任何其他建议吗?

+0

你不能只是去获得许可。你需要提升。这需要在流程启动时完成。 –

回答

18

documentation告诉你如何做到这一点。

调用SetEnvironmentVariable对系统环境变量没有影响。要以编程方式添加或修改系统环境变量,请将它们添加到HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment注册表项中,然后将WM_SETTINGCHANGE消息与lParam一起广播,并将其设置为字符串"Environment"。这使应用程序(如shell)能够获取更新。

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

一些示例代码:

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

documentation三个参数Environment.SetEnvironmentVariable超载说:

如果目标是EnvironmentVariableTarget.Machine,环境变量存储在HKEY_LOCAL_MACHINE \ SYSTEM \ ControlSet001 \控制\会话管理\环境的关键本地计算机的注册表。它也被复制到文件资源管理器的所有实例。然后,该环境变量由从文件资源管理器启动的任何新进程继承。

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

+0

正如我所说,调用'OpenSubKey'函数也会以异常结束,虽然密钥可用 – alex555

+0

正如我所说的,您需要运行这个提升。当你这样做时,你会发现它的工作原理。我确实测试了你知道的这个代码! –

+0

啊,它的工作原理!非常感谢你。是否有命令或参数来确认此UAC警告? – alex555

相关问题