2013-10-31 140 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

相關問題