В Linux отключена попытка применить переменные

This commit is contained in:
2026-06-04 20:04:58 +03:00
parent b6eb8026f0
commit 2565c138e4
2 changed files with 7 additions and 138 deletions

View File

@@ -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<string>();
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<string, string> variables)
{
foreach (var pair in variables)
{
System.Environment.SetEnvironmentVariable(pair.Key, pair.Value);
}
}
private static bool TryApplyViaSystemctl(
IReadOnlyDictionary<string, string> variables,
out string? errorMessage)
{
errorMessage = null;
var pairs = variables.ToList();
for (var offset = 0; offset < pairs.Count; offset += SystemctlBatchSize)
{
var arguments = new List<string> { "--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<string, string> variables,
out string? errorMessage)
{
var arguments = new List<string>();
foreach (var pair in variables)
{
arguments.Add($"{pair.Key}={pair.Value}");
}
return TryRunCommand("dbus-update-environment", arguments, out errorMessage);
}
private static bool TryRunSystemctl(IReadOnlyList<string> arguments, out string? errorMessage) =>
TryRunCommand("systemctl", arguments, out errorMessage);
private static bool TryRunCommand(
string fileName,
IReadOnlyList<string> 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<string, string> LoadManagedFile()
{