98 lines
3.1 KiB
C#
98 lines
3.1 KiB
C#
using System.Runtime.InteropServices;
|
|
using Sms.Environment;
|
|
|
|
namespace Sms.Environment.Windows;
|
|
|
|
public sealed class WindowsEnvironmentVariableStore : IEnvironmentVariableStore
|
|
{
|
|
private const int HWND_BROADCAST = 0xffff;
|
|
private const int WM_SETTINGCHANGE = 0x001A;
|
|
|
|
public string? Get(string name) =>
|
|
System.Environment.GetEnvironmentVariable(name, EnvironmentVariableTarget.User)
|
|
?? System.Environment.GetEnvironmentVariable(name, EnvironmentVariableTarget.Process);
|
|
|
|
public void Set(string name, string value)
|
|
{
|
|
System.Environment.SetEnvironmentVariable(name, value, EnvironmentVariableTarget.User);
|
|
System.Environment.SetEnvironmentVariable(name, value, EnvironmentVariableTarget.Process);
|
|
BroadcastEnvironmentChange();
|
|
}
|
|
|
|
public bool Exists(string name) => Get(name) is not null;
|
|
|
|
public IReadOnlyDictionary<string, string> GetAll(IEnumerable<string> names)
|
|
{
|
|
var result = new Dictionary<string, string>(StringComparer.Ordinal);
|
|
foreach (var name in names)
|
|
{
|
|
var value = Get(name);
|
|
if (value is not null)
|
|
{
|
|
result[name] = value;
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
public IReadOnlyDictionary<string, string> GetProcessEnvironment() =>
|
|
ToDictionary(System.Environment.GetEnvironmentVariables(EnvironmentVariableTarget.Process));
|
|
|
|
public IReadOnlyDictionary<string, string> GetUserPersistedEnvironment() =>
|
|
ToDictionary(System.Environment.GetEnvironmentVariables(EnvironmentVariableTarget.User));
|
|
|
|
public bool IsPersistedInUserStore(string name) =>
|
|
System.Environment.GetEnvironmentVariable(name, EnvironmentVariableTarget.User) is not null;
|
|
|
|
public void RemoveFromUserStore(string name)
|
|
{
|
|
System.Environment.SetEnvironmentVariable(name, null, EnvironmentVariableTarget.User);
|
|
System.Environment.SetEnvironmentVariable(name, null, EnvironmentVariableTarget.Process);
|
|
BroadcastEnvironmentChange();
|
|
}
|
|
|
|
private static Dictionary<string, string> ToDictionary(System.Collections.IDictionary source)
|
|
{
|
|
var result = new Dictionary<string, string>(StringComparer.Ordinal);
|
|
foreach (string key in source.Keys)
|
|
{
|
|
result[key] = source[key]?.ToString() ?? string.Empty;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
private static void BroadcastEnvironmentChange()
|
|
{
|
|
try
|
|
{
|
|
_ = NativeMethods.SendMessageTimeout(
|
|
HWND_BROADCAST,
|
|
WM_SETTINGCHANGE,
|
|
IntPtr.Zero,
|
|
"Environment",
|
|
0,
|
|
1000,
|
|
out _);
|
|
}
|
|
catch
|
|
{
|
|
// Non-critical: new processes still see updated registry values.
|
|
}
|
|
}
|
|
|
|
private static class NativeMethods
|
|
{
|
|
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
|
public static extern IntPtr SendMessageTimeout(
|
|
int hWnd,
|
|
int msg,
|
|
IntPtr wParam,
|
|
string lParam,
|
|
int fuFlags,
|
|
int uTimeout,
|
|
out IntPtr lpdwResult);
|
|
}
|
|
}
|