From a827bd608b2861de71c84a07de6ecd1f4aa1f79a Mon Sep 17 00:00:00 2001 From: Roman Pytkov Date: Thu, 4 Jun 2026 21:48:07 +0300 Subject: [PATCH] =?UTF-8?q?=D0=A3=D0=B1=D1=80=D0=B0=D0=BD=D1=8B=20=D0=BF?= =?UTF-8?q?=D0=BE=D0=BF=D1=8B=D1=82=D0=BA=D0=B8=20=D0=BF=D1=80=D0=B8=D0=BC?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D1=82=D1=8C=20=D0=BF=D0=B5=D1=80=D0=B5=D0=BC?= =?UTF-8?q?=D0=B5=D0=BD=D0=BD=D1=8B=D0=B5=20=D0=BE=D0=BA=D1=80=D1=83=D0=B6?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D1=8F=20=D0=BA=20=D1=81=D0=B5=D1=81=D1=81?= =?UTF-8?q?=D0=B8=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 6 +- .../LinuxEnvironmentVariableStore.cs | 12 ---- .../WindowsEnvironmentVariableStore.cs | 58 ------------------- .../EnvironmentReloadResult.cs | 8 --- .../IEnvironmentVariableStore.cs | 2 - .../Views/MainWindow.axaml | 15 +---- .../Services/EnvironmentVariablesService.cs | 11 ---- .../EnvironmentVariableRowViewModel.cs | 17 ------ .../MainWindowViewModel.cs | 27 +-------- 9 files changed, 4 insertions(+), 152 deletions(-) delete mode 100644 src/Sms.Environment/EnvironmentReloadResult.cs diff --git a/README.md b/README.md index 4125bfb..ecb7654 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@ dotnet run --project src/Sms.TaskTwo.Avalonia/Sms.TaskTwo.Avalonia.csproj {"SMS_MEAL_SERVER_URL":"URL сервера","SMS_MEAL_API_KEY":"ключ API"} ``` -Переменная записывается тем же механизмом, что и остальные, и доступна другим процессам после применения окружения ОС. +Переменная записывается тем же механизмом, что и остальные, и доступна другим процессам после перезапуска сессии или приложений. ## Логирование @@ -72,12 +72,10 @@ dotnet run --project src/Sms.TaskTwo.Avalonia/Sms.TaskTwo.Avalonia.csproj ### Windows - Чтение/запись: реестр `HKEY_CURRENT_USER\Environment`. -- **Применить к сессии** (`ReloadEnvironment`): обновляет env текущего процесса и рассылает `WM_SETTINGCHANGE` для других GUI-приложений. ### Linux -- Запись в `~/.config/environment.d/` (systemd `KEY=value`). -- **Применить к сессии** не поддерживается: переменные подхватываются после перезапуска login-сессии. +- Запись в `~/.config/environment.d/` (systemd `KEY=value`); переменные подхватываются после перезапуска login-сессии. ## Предположения (ТЗ) diff --git a/src/Sms.Environment.Linux/LinuxEnvironmentVariableStore.cs b/src/Sms.Environment.Linux/LinuxEnvironmentVariableStore.cs index 4718d63..acfd837 100644 --- a/src/Sms.Environment.Linux/LinuxEnvironmentVariableStore.cs +++ b/src/Sms.Environment.Linux/LinuxEnvironmentVariableStore.cs @@ -52,7 +52,6 @@ public sealed class LinuxEnvironmentVariableStore : IEnvironmentVariableStore var managed = LoadManagedFile(); managed[name] = value; WriteManagedFileAtomic(managed); - System.Environment.SetEnvironmentVariable(name, value); } catch (Exception ex) when (ex is UnauthorizedAccessException or IOException) { @@ -115,8 +114,6 @@ public sealed class LinuxEnvironmentVariableStore : IEnvironmentVariableStore WriteConfFileAtomic(file, variables); } - - System.Environment.SetEnvironmentVariable(name, null); } catch (Exception ex) when (ex is UnauthorizedAccessException or IOException) { @@ -126,15 +123,6 @@ public sealed class LinuxEnvironmentVariableStore : IEnvironmentVariableStore } } - public EnvironmentReloadResult ReloadEnvironment() => - new() - { - Success = false, - Message = - "Применение переменных к сессии в Linux не поддерживается. " + - "Значения сохраняются в ~/.config/environment.d/ и подхватываются после перезапуска login-сессии.", - }; - private Dictionary LoadManagedFile() { if (!File.Exists(_managedFilePath)) diff --git a/src/Sms.Environment.Windows/WindowsEnvironmentVariableStore.cs b/src/Sms.Environment.Windows/WindowsEnvironmentVariableStore.cs index 76e3c0a..fb22878 100644 --- a/src/Sms.Environment.Windows/WindowsEnvironmentVariableStore.cs +++ b/src/Sms.Environment.Windows/WindowsEnvironmentVariableStore.cs @@ -1,4 +1,3 @@ -using System.Runtime.InteropServices; using Microsoft.Win32; using Sms.Environment; @@ -6,8 +5,6 @@ namespace Sms.Environment.Windows; public sealed class WindowsEnvironmentVariableStore : IEnvironmentVariableStore { - private const int HWND_BROADCAST = 0xffff; - private const int WM_SETTINGCHANGE = 0x001A; private const string EnvironmentKeyPath = "Environment"; public string? Get(string name) => @@ -25,8 +22,6 @@ public sealed class WindowsEnvironmentVariableStore : IEnvironmentVariableStore using var key = Registry.CurrentUser.OpenSubKey(EnvironmentKeyPath, writable: true) ?? Registry.CurrentUser.CreateSubKey(EnvironmentKeyPath, writable: true); key.SetValue(name, value, RegistryValueKind.ExpandString); - System.Environment.SetEnvironmentVariable(name, value, EnvironmentVariableTarget.Process); - BroadcastEnvironmentChange(); } public bool Exists(string name) => Get(name) is not null; @@ -79,27 +74,6 @@ public sealed class WindowsEnvironmentVariableStore : IEnvironmentVariableStore { using var key = Registry.CurrentUser.OpenSubKey(EnvironmentKeyPath, writable: true); key?.DeleteValue(name, throwOnMissingValue: false); - System.Environment.SetEnvironmentVariable(name, null, EnvironmentVariableTarget.Process); - BroadcastEnvironmentChange(); - } - - public EnvironmentReloadResult ReloadEnvironment() - { - var variables = GetUserPersistedEnvironment(); - foreach (var pair in variables) - { - System.Environment.SetEnvironmentVariable(pair.Key, pair.Value, EnvironmentVariableTarget.Process); - } - - BroadcastEnvironmentChange(); - - return new EnvironmentReloadResult - { - Success = true, - Message = variables.Count == 0 - ? "Пользовательских переменных для применения нет." - : $"Применено {variables.Count} переменных к текущему процессу и отправлено WM_SETTINGCHANGE для других приложений.", - }; } private static Dictionary ToDictionary(System.Collections.IDictionary source) @@ -112,36 +86,4 @@ public sealed class WindowsEnvironmentVariableStore : IEnvironmentVariableStore 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); - } } diff --git a/src/Sms.Environment/EnvironmentReloadResult.cs b/src/Sms.Environment/EnvironmentReloadResult.cs deleted file mode 100644 index bc958d3..0000000 --- a/src/Sms.Environment/EnvironmentReloadResult.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Sms.Environment; - -public sealed class EnvironmentReloadResult -{ - public required bool Success { get; init; } - - public required string Message { get; init; } -} diff --git a/src/Sms.Environment/IEnvironmentVariableStore.cs b/src/Sms.Environment/IEnvironmentVariableStore.cs index 109aa9a..8a9f250 100644 --- a/src/Sms.Environment/IEnvironmentVariableStore.cs +++ b/src/Sms.Environment/IEnvironmentVariableStore.cs @@ -19,6 +19,4 @@ public interface IEnvironmentVariableStore bool IsPersistedInUserStore(string name); void RemoveFromUserStore(string name); - - EnvironmentReloadResult ReloadEnvironment(); } diff --git a/src/Sms.TaskTwo.Avalonia/Views/MainWindow.axaml b/src/Sms.TaskTwo.Avalonia/Views/MainWindow.axaml index c5a8794..5e848a1 100644 --- a/src/Sms.TaskTwo.Avalonia/Views/MainWindow.axaml +++ b/src/Sms.TaskTwo.Avalonia/Views/MainWindow.axaml @@ -22,7 +22,7 @@ -