¿Cómo establecer la variable de entorno del sistema en C #?

Estoy tratando de establecer una variable de entorno del sistema en mi aplicación, pero obtengo una SecurityException . Probé todo lo que encontré en google, sin éxito. Aquí está mi código (nota, que soy administrador de mi pc y ejecuto VS2012 como administrador):

Intento 1

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

Intento 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"); } 

Intento 3 También intenté adaptar mi aplicación a los privilegios del administrador .

¿Tiene alguna otra sugerencia?

La documentación te dice cómo hacer esto.

Llamar a SetEnvironmentVariable no tiene ningún efecto en las variables de entorno del sistema. Para agregar o modificar mediante progtwigción las variables de entorno del sistema, agréguelos a la clave de registro HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment y luego transmita un mensaje WM_SETTINGCHANGE con lParam establecido en la cadena "Environment" . Esto permite que las aplicaciones, como el shell, recojan sus actualizaciones.

Por lo tanto, debe escribir en la configuración del registro en la que ya está intentando escribir. Y luego transmita un mensaje WM_SETTINGCHANGE como se detalla arriba. Deberá ejecutar derechos elevados para que esto tenga éxito.

Un código de ejemplo:

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

Sin embargo, aunque este código funciona, el .NET Framework proporciona la funcionalidad para realizar la misma tarea de forma mucho más simple.

 Environment.SetEnvironmentVariable("TEST1", "TestValue", EnvironmentVariableTarget.Machine); 

La documentación para la sobrecarga de Environment.SetEnvironmentVariable tres argumentos dice:

Si el objective es EnvironmentVariableTarget.Machine, la variable de entorno se almacena en la clave HKEY_LOCAL_MACHINE \ SYSTEM \ ControlSet001 \ Control \ Session Manager \ Environment del registro de la computadora local. También se copia en todas las instancias de File Explorer. La variable de entorno luego es heredada por cualquier proceso nuevo que se inicie desde el Explorador de archivos.

Si el objective es Usuario o Máquina, el mensaje WM_SETTINGCHANGE de Windows notificará a otras aplicaciones de la operación establecida.