Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set system environment variable in C#?

I'm trying to set a system environment variable in my application, but get an SecurityException. I tested everything I found in google - without success. Here is my code (note, that I'm administrator of my pc and run VS2012 as admin):

Attempt 1

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

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

Attempt 3 Also I tried to fit out my app with administrator priviliges.

Do you have any other suggestions?

like image 401
alex555 Avatar asked Oct 31 '13 11:10

alex555


People also ask

How do I set system environment variables?

On the Windows taskbar, right-click the Windows icon and select System. In the Settings window, under Related Settings, click Advanced system settings. On the Advanced tab, click Environment Variables. Click New to create a new environment variable.

How do I set environment variable in CMD?

To set (or change) a environment variable, use command " set varname=value ". There shall be no spaces before and after the '=' sign. To unset an environment variable, use " set varname= ", i.e., set it to an empty string.

What is environment variable in C programming?

Environment variable is a global variable that can affect the way the running process will behave on the system.

How does Setenv work in C?

DESCRIPTION. The setenv() function shall update or add a variable in the environment of the calling process. The envname argument points to a string containing the name of an environment variable to be added or altered. The environment variable shall be set to the value to which envval points.


1 Answers

The documentation tells you how to do this.

Calling SetEnvironmentVariable has no effect on the system environment variables. To programmatically add or modify system environment variables, add them to the HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment registry key, then broadcast a WM_SETTINGCHANGE message with lParam set to the string "Environment". This allows applications, such as the shell, to pick up your updates.

So, you need to write to the registry setting that you are already attempting to write to. And then broadcast a WM_SETTINGCHANGE message as detailed above. You will need to be running with elevated rights in order for this to succeed.

Some example code:

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

However, whilst this code does work, the .net framework provides functionality to perform the same task much more simply.

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

The documentation for the three argument Environment.SetEnvironmentVariable overload says:

If target is EnvironmentVariableTarget.Machine, the environment variable is stored in the HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Session Manager\Environment key of the local computer's registry. It is also copied to all instances of File Explorer. The environment variable is then inherited by any new processes that are launched from File Explorer.

If target is User or Machine, other applications are notified of the set operation by a Windows WM_SETTINGCHANGE message.

like image 75
David Heffernan Avatar answered Oct 12 '22 23:10

David Heffernan