From 2565c138e49684d3089d9fb6134a4bae8b727acd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9F=D1=8B=D1=82=D0=BA=D0=BE=D0=B2=20=D0=A0=D0=BE=D0=BC?= =?UTF-8?q?=D0=B0=D0=BD?= Date: Thu, 4 Jun 2026 20:04:58 +0300 Subject: [PATCH] =?UTF-8?q?=D0=92=20Linux=20=D0=BE=D1=82=D0=BA=D0=BB=D1=8E?= =?UTF-8?q?=D1=87=D0=B5=D0=BD=D0=B0=20=D0=BF=D0=BE=D0=BF=D1=8B=D1=82=D0=BA?= =?UTF-8?q?=D0=B0=20=D0=BF=D1=80=D0=B8=D0=BC=D0=B5=D0=BD=D0=B8=D1=82=D1=8C?= =?UTF-8?q?=20=D0=BF=D0=B5=D1=80=D0=B5=D0=BC=D0=B5=D0=BD=D0=BD=D1=8B=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 3 +- .../LinuxEnvironmentVariableStore.cs | 142 +----------------- 2 files changed, 7 insertions(+), 138 deletions(-) diff --git a/README.md b/README.md index 5ae2e2b..35d54aa 100644 --- a/README.md +++ b/README.md @@ -77,8 +77,7 @@ dotnet run --project src/Sms.TaskTwo.Avalonia/Sms.TaskTwo.Avalonia.csproj ### Linux - Запись в `~/.config/environment.d/` (systemd `KEY=value`). -- **Применить к сессии** (`ReloadEnvironment`): текущий процесс, `systemctl --user set-environment`, при наличии — `dbus-update-environment`. -- Новые login-сессии могут потребовать перелогин — ограничение systemd. +- **Применить к сессии** не поддерживается: переменные подхватываются после перезапуска login-сессии. ## Предположения (ТЗ) diff --git a/src/Sms.Environment.Linux/LinuxEnvironmentVariableStore.cs b/src/Sms.Environment.Linux/LinuxEnvironmentVariableStore.cs index cbd4fd2..cbfd938 100644 --- a/src/Sms.Environment.Linux/LinuxEnvironmentVariableStore.cs +++ b/src/Sms.Environment.Linux/LinuxEnvironmentVariableStore.cs @@ -1,4 +1,3 @@ -using System.Diagnostics; using Sms.Environment; namespace Sms.Environment.Linux; @@ -6,7 +5,6 @@ namespace Sms.Environment.Linux; public sealed class LinuxEnvironmentVariableStore : IEnvironmentVariableStore { private const string ManagedFileName = "99-sms-task-two.conf"; - private const int SystemctlBatchSize = 32; private readonly string _managedFilePath; private readonly string _environmentDirectory; @@ -121,7 +119,6 @@ public sealed class LinuxEnvironmentVariableStore : IEnvironmentVariableStore } System.Environment.SetEnvironmentVariable(name, null); - TryRunSystemctl(["--user", "unset-environment", name], out _); } catch (Exception ex) when (ex is UnauthorizedAccessException or IOException) { @@ -131,141 +128,14 @@ public sealed class LinuxEnvironmentVariableStore : IEnvironmentVariableStore } } - public EnvironmentReloadResult ReloadEnvironment() - { - var variables = GetUserPersistedEnvironment(); - ApplyToCurrentProcess(variables); - - if (variables.Count == 0) + public EnvironmentReloadResult ReloadEnvironment() => + new() { - return new EnvironmentReloadResult - { - Success = true, - Message = "Пользовательских переменных для применения нет.", - }; - } - - var messages = new List(); - if (TryApplyViaSystemctl(variables, out var systemctlError)) - { - messages.Add("systemd user manager обновлён (systemctl --user set-environment)."); - } - else if (systemctlError is not null) - { - messages.Add($"systemctl: {systemctlError}"); - } - - if (TryApplyViaDbusUpdateEnvironment(variables, out var dbusError)) - { - messages.Add("D-Bus session обновлён (dbus-update-environment)."); - } - else if (dbusError is not null) - { - messages.Add($"dbus-update-environment: {dbusError}"); - } - - var processApplied = messages.Count > 0 || variables.Count > 0; - return new EnvironmentReloadResult - { - Success = processApplied, - Message = processApplied - ? $"Применено {variables.Count} переменных к текущему процессу. {string.Join(' ', messages)}" - : "Не удалось применить переменные к сессии.", + Success = false, + Message = + "Применение переменных к сессии в Linux не поддерживается. " + + "Значения сохраняются в ~/.config/environment.d/ и подхватываются после перезапуска login-сессии.", }; - } - - private static void ApplyToCurrentProcess(IReadOnlyDictionary variables) - { - foreach (var pair in variables) - { - System.Environment.SetEnvironmentVariable(pair.Key, pair.Value); - } - } - - private static bool TryApplyViaSystemctl( - IReadOnlyDictionary variables, - out string? errorMessage) - { - errorMessage = null; - var pairs = variables.ToList(); - for (var offset = 0; offset < pairs.Count; offset += SystemctlBatchSize) - { - var arguments = new List { "--user", "set-environment" }; - foreach (var pair in pairs.Skip(offset).Take(SystemctlBatchSize)) - { - arguments.Add($"{pair.Key}={pair.Value}"); - } - - if (!TryRunSystemctl(arguments, out errorMessage)) - { - return false; - } - } - - return true; - } - - private static bool TryApplyViaDbusUpdateEnvironment( - IReadOnlyDictionary variables, - out string? errorMessage) - { - var arguments = new List(); - foreach (var pair in variables) - { - arguments.Add($"{pair.Key}={pair.Value}"); - } - - return TryRunCommand("dbus-update-environment", arguments, out errorMessage); - } - - private static bool TryRunSystemctl(IReadOnlyList arguments, out string? errorMessage) => - TryRunCommand("systemctl", arguments, out errorMessage); - - private static bool TryRunCommand( - string fileName, - IReadOnlyList arguments, - out string? errorMessage) - { - errorMessage = null; - try - { - var startInfo = new ProcessStartInfo - { - FileName = fileName, - RedirectStandardError = true, - RedirectStandardOutput = true, - UseShellExecute = false, - }; - foreach (var argument in arguments) - { - startInfo.ArgumentList.Add(argument); - } - - using var process = Process.Start(startInfo); - if (process is null) - { - errorMessage = "не удалось запустить процесс"; - return false; - } - - var stderr = process.StandardError.ReadToEnd(); - process.WaitForExit(5000); - if (process.ExitCode == 0) - { - return true; - } - - errorMessage = string.IsNullOrWhiteSpace(stderr) - ? $"код выхода {process.ExitCode}" - : stderr.Trim(); - return false; - } - catch (Exception ex) - { - errorMessage = ex.Message; - return false; - } - } private Dictionary LoadManagedFile() {