TeamCity.CSharpInteractive/ExitTracker.cs (48 lines of code) (raw):
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable SwitchStatementHandlesSomeKnownEnumValuesWithDefault
namespace TeamCity.CSharpInteractive;
using System.Diagnostics.CodeAnalysis;
[ExcludeFromCodeCoverage]
internal class ExitTracker : IExitTracker
{
private readonly ISettings _settings;
private readonly IEnvironment _environment;
private readonly IPresenter<Summary> _summaryPresenter;
private readonly CancellationTokenSource _cancellationTokenSource;
private volatile bool _isTerminating;
public ExitTracker(
ISettings settings,
IEnvironment environment,
IPresenter<Summary> summaryPresenter,
CancellationTokenSource cancellationTokenSource)
{
_settings = settings;
_environment = environment;
_summaryPresenter = summaryPresenter;
_cancellationTokenSource = cancellationTokenSource;
}
public bool IsTerminating => _isTerminating;
public IDisposable Track()
{
switch (_settings.InteractionMode)
{
case InteractionMode.Interactive:
System.Console.CancelKeyPress += ConsoleOnCancelKeyPress;
return Disposable.Create(() => System.Console.CancelKeyPress -= ConsoleOnCancelKeyPress);
default:
AppDomain.CurrentDomain.ProcessExit += CurrentDomainOnProcessExit;
return Disposable.Create(() => AppDomain.CurrentDomain.ProcessExit -= CurrentDomainOnProcessExit);
}
}
private void CurrentDomainOnProcessExit(object? sender, EventArgs e)
{
_isTerminating = true;
try
{
_cancellationTokenSource.Cancel();
}
catch
{
// ignored
}
_summaryPresenter.Show(Summary.Empty);
}
private void ConsoleOnCancelKeyPress(object? sender, ConsoleCancelEventArgs e) => _environment.Exit(0);
}