mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-29 00:24:42 +01:00
Set variables - fire and forget notify
This commit is contained in:
@@ -4,8 +4,13 @@
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security;
|
||||
using EnvironmentVariables.Helpers.Win32;
|
||||
using EnvironmentVariables.Models;
|
||||
using Microsoft.Win32;
|
||||
|
||||
namespace EnvironmentVariables.Helpers
|
||||
{
|
||||
@@ -35,6 +40,55 @@ namespace EnvironmentVariables.Helpers
|
||||
return null;
|
||||
}
|
||||
|
||||
private static RegistryKey OpenEnvironmentKeyIfExists(bool fromMachine, bool writable)
|
||||
{
|
||||
RegistryKey baseKey;
|
||||
string keyName;
|
||||
|
||||
if (fromMachine)
|
||||
{
|
||||
baseKey = Registry.LocalMachine;
|
||||
keyName = @"System\CurrentControlSet\Control\Session Manager\Environment";
|
||||
}
|
||||
else
|
||||
{
|
||||
baseKey = Registry.CurrentUser;
|
||||
keyName = "Environment";
|
||||
}
|
||||
|
||||
return baseKey.OpenSubKey(keyName, writable: writable);
|
||||
}
|
||||
|
||||
private static void SetEnvironmentVariableFromRegistryWithoutNotify(string variable, string value, bool fromMachine)
|
||||
{
|
||||
using (RegistryKey environmentKey = OpenEnvironmentKeyIfExists(fromMachine, writable: true))
|
||||
{
|
||||
if (environmentKey != null)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
environmentKey.DeleteValue(variable, throwOnMissingValue: false);
|
||||
}
|
||||
else
|
||||
{
|
||||
environmentKey.SetValue(variable, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void NotifyEnvironmentChange()
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
// send a WM_SETTINGCHANGE message to all windows
|
||||
fixed (char* lParam = "Environment")
|
||||
{
|
||||
_ = NativeMethods.SendNotifyMessage(new IntPtr(NativeMethods.HWND_BROADCAST), NativeMethods.WM_SETTINGCHANGE, IntPtr.Zero, (IntPtr)lParam);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static void GetVariables(EnvironmentVariableTarget target, VariablesSet set)
|
||||
{
|
||||
var variables = Environment.GetEnvironmentVariables(target);
|
||||
@@ -56,59 +110,73 @@ namespace EnvironmentVariables.Helpers
|
||||
|
||||
internal static bool SetVariable(Variable variable)
|
||||
{
|
||||
EnvironmentVariableTarget target = variable.ParentType switch
|
||||
bool fromMachine = variable.ParentType switch
|
||||
{
|
||||
VariablesSetType.Profile => EnvironmentVariableTarget.User,
|
||||
VariablesSetType.User => EnvironmentVariableTarget.User,
|
||||
VariablesSetType.System => EnvironmentVariableTarget.Machine,
|
||||
VariablesSetType.Profile => false,
|
||||
VariablesSetType.User => false,
|
||||
VariablesSetType.System => true,
|
||||
_ => throw new NotImplementedException(),
|
||||
};
|
||||
|
||||
try
|
||||
SetEnvironmentVariableFromRegistryWithoutNotify(variable.Name, variable.Values, fromMachine);
|
||||
NotifyEnvironmentChange();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
internal static bool SetVariables(List<Variable> variables, VariablesSetType type)
|
||||
{
|
||||
bool fromMachine = type switch
|
||||
{
|
||||
Environment.SetEnvironmentVariable(variable.Name, variable.Values, target);
|
||||
}
|
||||
catch (SecurityException)
|
||||
VariablesSetType.Profile => false,
|
||||
VariablesSetType.User => false,
|
||||
VariablesSetType.System => true,
|
||||
_ => throw new NotImplementedException(),
|
||||
};
|
||||
|
||||
foreach (Variable variable in variables)
|
||||
{
|
||||
// Permission denied (e.g. trying to change System variable while running non-elevated)
|
||||
// Show specific error message
|
||||
return false;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// Something else went wrong
|
||||
return false;
|
||||
SetEnvironmentVariableFromRegistryWithoutNotify(variable.Name, variable.Values, fromMachine);
|
||||
}
|
||||
|
||||
NotifyEnvironmentChange();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
internal static bool UnsetVariable(Variable variable)
|
||||
{
|
||||
EnvironmentVariableTarget target = variable.ParentType switch
|
||||
bool fromMachine = variable.ParentType switch
|
||||
{
|
||||
VariablesSetType.Profile => EnvironmentVariableTarget.User,
|
||||
VariablesSetType.User => EnvironmentVariableTarget.User,
|
||||
VariablesSetType.System => EnvironmentVariableTarget.Machine,
|
||||
VariablesSetType.Profile => false,
|
||||
VariablesSetType.User => false,
|
||||
VariablesSetType.System => true,
|
||||
_ => throw new NotImplementedException(),
|
||||
};
|
||||
|
||||
try
|
||||
SetEnvironmentVariableFromRegistryWithoutNotify(variable.Name, null, fromMachine);
|
||||
NotifyEnvironmentChange();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
internal static bool UnsetVariables(List<Variable> variables, VariablesSetType type)
|
||||
{
|
||||
bool fromMachine = type switch
|
||||
{
|
||||
Environment.SetEnvironmentVariable(variable.Name, string.Empty, target);
|
||||
}
|
||||
catch (SecurityException)
|
||||
VariablesSetType.Profile => false,
|
||||
VariablesSetType.User => false,
|
||||
VariablesSetType.System => true,
|
||||
_ => throw new NotImplementedException(),
|
||||
};
|
||||
|
||||
foreach (Variable variable in variables)
|
||||
{
|
||||
// Permission denied (e.g. trying to change System variable while running non-elevated)
|
||||
// Show specific error message
|
||||
return false;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// Something else went wrong
|
||||
return false;
|
||||
SetEnvironmentVariableFromRegistryWithoutNotify(variable.Name, null, fromMachine);
|
||||
}
|
||||
|
||||
NotifyEnvironmentChange();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace EnvironmentVariables.Helpers.Win32
|
||||
{
|
||||
public static class NativeMethods
|
||||
{
|
||||
internal const int HWND_BROADCAST = 0xffff;
|
||||
|
||||
internal const int WM_SETTINGCHANGE = 0x001A;
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
|
||||
internal static extern int SendNotifyMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);
|
||||
}
|
||||
}
|
||||
@@ -222,7 +222,7 @@
|
||||
<value>Changes were made outside of this app.</value>
|
||||
</data>
|
||||
<data name="StateNotUpToDateInfoBar.Message" xml:space="preserve">
|
||||
<value>Variables have been modified. Reload to get the latest changes.</value>
|
||||
<value>Variables included in applied profile have been modified. Review the latest changes before applying the profile again.</value>
|
||||
</data>
|
||||
<data name="CancelBtn" xml:space="preserve">
|
||||
<value>Cancel</value>
|
||||
|
||||
Reference in New Issue
Block a user