Reputation: 3065
I need to add a Windows Environment Variable like the existing in windows. I mean :
When you run the following line in the cmd.exe :
echo %appdata% //outputs something like C:/Users/blablabla
// It's saved in windows by default !
I'm making a simple Winform application that makes the creation of the windows environment variables easy with C#
I have tried :
System.Environment.SetEnvironmentVariable("test", "testvalue", EnvironmentVariableTarget.Machine);
I tried with this but neither :
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);
using (var envKey = Registry.LocalMachine.OpenSubKey(
@"SYSTEM\CurrentControlSet\Control\Session Manager\Environment",
true))
{
Contract.Assert(envKey != null, @"registry key is missing!");
envKey.SetValue("artyom", "TestValue");
SendNotifyMessage((IntPtr)HWND_BROADCAST, WM_SETTINGCHANGE,
(UIntPtr)0, "Environment");
}
// it is assumed after this , the list should display this value, but nothing happens ! No exceptions, nothing
And read :
msdn docs - Other link here ...
The EnvironmentVariableTarget.Machine doesn't seems to help at all.
If this process is successful, i would be capable of do this in cmd.exe
echo %test% // and outputs "testvalue"
Keep in mind i'm testing all this code when the user click a button and i'm working in WinForms it's possible to do this with C# or not ? Any help is appreciated, thanks
Upvotes: 2
Views: 1413
Reputation: 8763
You can try adding a call to NotifyUserEnvironmentVariableChanged - but I think I've had mixed results.
[DllImport( "user32.dll", SetLastError = true, CharSet = CharSet.Auto )]
static extern bool SendNotifyMessage( IntPtr hWnd, uint Msg,UIntPtr wParam, string lParam );
public static void NotifyUserEnvironmentVariableChanged()
{
const int HWND_BROADCAST = 0xffff;
const uint WM_SETTINGCHANGE = 0x001a;
SendNotifyMessage( ( IntPtr )HWND_BROADCAST, WM_SETTINGCHANGE, ( UIntPtr )0, "Environment" );
}
From here:
Variables are added by creating a new value under this key or by modifying a value if it already exists. To delete a variable, you simply delete its Registry value, unless you are removing part of an expanded value, such as PATH, in which case you only remove the part you want.
At this point, Windows will not be aware of your changes unless you log off or reboot. To get around this, SetEnv will broadcast a WM_SETTINGCHANGE to all of the windows in the system. This allows other running applications—for example, Explorer.exe—to be notified of your change. If you run SetEnv from a command prompt, this will not update the environment variable for the current DOS window. This is mainly due to the fact that a process (SetEnv) cannot change the environment of its parent (The Command Prompt). However, any new DOS/Command Prompts that you open will show the new variable/value.
Broadcasting this message results in a slight delay (whilst the open windows process it) of around 2-3 seconds, so it may appear that SetEnv has hung. This is not the case.
I believe I have noticed both the delay, and also the issue with needing to open a new command prompt.
Upvotes: 2