финал

This commit is contained in:
2026-09-14 22:34:33 +02:00
parent 45e8e4873a
commit fc91250663
6 changed files with 343 additions and 120 deletions
+37 -58
View File
@@ -145,11 +145,21 @@ public sealed class InstallerService
if (!isUninstall)
{
// IMPORTANT:
// SpotX asks interactively about these options when
// neither switch is supplied. Since our GUI has no
// interactive PowerShell input, always provide an
// explicit answer.
if (options.BlockUpdates)
arguments.Add("-block_update_on");
else
arguments.Add("-block_update_off");
if (options.HidePodcasts)
arguments.Add("-podcasts_off");
else
arguments.Add("-podcasts_on");
if (options.HidePremium)
arguments.Add("-adsections_off");
@@ -205,8 +215,6 @@ public sealed class InstallerService
string lower = line.ToLowerInvariant();
// Никакого фальшивого +2%.
// Только изменение текста статуса по реальному выводу.
if (lower.Contains("download") ||
lower.Contains("скач"))
{
@@ -243,16 +251,20 @@ public sealed class InstallerService
if (exitCode == 0)
{
progress.Report(
(100,
(
100,
isUninstall
? "Восстановление завершено"
: "Установка завершена"));
: "Установка завершена"
));
}
else
{
progress.Report(
(100,
$"Ошибка установки (код {exitCode})"));
(
100,
$"Ошибка установки (код {exitCode})"
));
}
return exitCode;
@@ -277,17 +289,11 @@ public sealed class InstallerService
Action<string> onLine,
CancellationToken ct)
{
var tcs =
new TaskCompletionSource<int>(
TaskCreationOptions.RunContinuationsAsynchronously);
var psi = new ProcessStartInfo
{
FileName = file,
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,
CreateNoWindow = true
};
@@ -295,14 +301,11 @@ public sealed class InstallerService
foreach (string argument in arguments)
psi.ArgumentList.Add(argument);
var process = new Process
using var process = new Process
{
StartInfo = psi,
EnableRaisingEvents = true
StartInfo = psi
};
int finished = 0;
process.OutputDataReceived += (_, e) =>
{
if (e.Data is not null)
@@ -315,31 +318,26 @@ public sealed class InstallerService
onLine(e.Data);
};
process.Exited += (_, _) =>
ct.ThrowIfCancellationRequested();
if (!process.Start())
{
if (Interlocked.Exchange(ref finished, 1) != 0)
return;
throw new InvalidOperationException(
$"Не удалось запустить процесс: {file}");
}
try
{
tcs.TrySetResult(process.ExitCode);
}
catch
{
tcs.TrySetResult(-1);
}
finally
{
process.Dispose();
}
};
process.BeginOutputReadLine();
process.BeginErrorReadLine();
using CancellationTokenRegistration registration =
ct.Register(() =>
try
{
if (Interlocked.Exchange(ref finished, 1) != 0)
return;
await process.WaitForExitAsync(ct)
.ConfigureAwait(false);
return process.ExitCode;
}
catch (OperationCanceledException)
{
try
{
if (!process.HasExited)
@@ -353,28 +351,10 @@ public sealed class InstallerService
// Процесс уже мог завершиться.
}
tcs.TrySetCanceled(ct);
});
try
{
ct.ThrowIfCancellationRequested();
if (!process.Start())
throw new InvalidOperationException(
$"Не удалось запустить процесс: {file}");
process.BeginOutputReadLine();
process.BeginErrorReadLine();
return await tcs.Task.ConfigureAwait(false);
}
catch
{
try
{
if (!process.HasExited)
process.Kill(entireProcessTree: true);
await process.WaitForExitAsync()
.ConfigureAwait(false);
}
catch
{
@@ -385,4 +365,3 @@ public sealed class InstallerService
}
}
}