blorb
blorb

Reputation: 87

C# Updating Environment Variable - SendMessageTimeout

I'm trying to set an system environment variable, I note for the change to be reflected I've got to do a SendMessageTimeout to update the windows.

I can get it to run, and return a 0 result, but the environment variable is not ever actually updated.

[Flags]
public enum SendMessageTimeoutFlags : uint
{
    SMTO_NORMAL = 0x0,
    SMTO_BLOCK = 0x1,
    SMTO_ABORTIFHUNG = 0x2,
    SMTO_NOTIMEOUTIFNOTHUNG = 0x8
}

[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern IntPtr SendMessageTimeout(
IntPtr hWnd,
uint Msg,
UIntPtr wParam,
IntPtr lParam,
SendMessageTimeoutFlags fuFlags,
uint uTimeout,
out UIntPtr lpdwResult);


string reg_subkey = "Test1";
string reg_name = @"HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment";
Registry.SetValue(reg_name, reg_subkey, "testing", RegistryValueKind.String);

IntPtr HWND_BROADCAST = new IntPtr(0xffff);
const uint WM_WININICHANGE = 0x001A;
const uint WM_SETTINGCHANGE = WM_WININICHANGE;
const int MSG_TIMEOUT = 15000;
UIntPtr RESULT;

string ENVIRONMENT = "Environment";

SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, UIntPtr.Zero, (IntPtr)Marshal.StringToHGlobalAnsi(ENVIRONMENT), SendMessageTimeoutFlags.SMTO_ABORTIFHUNG, MSG_TIMEOUT, out RESULT);

Upvotes: 2

Views: 3679

Answers (2)

Prometheus
Prometheus

Reputation: 56

I would try using the Environment.SetEnvironmentVariable function followed by the SendMessageTimeout, this has worked in my teams testing with updating the PATH variable in the machine context. We also found to the contrary of documentation that Environment.SetEnvironmentVariable only works by itself when creating a new variable. We are testing in a scenario where the parent process must get the updated PATH variable.

Upvotes: 1

Rich
Rich

Reputation: 735

The easiest way is to use Environment.SetEnvironmentVariable. This calls SendMessageTimeout internally.

Upvotes: 4

Related Questions