protected virtual Task DbGc() { const string sql = "delete SheepJaxMessages where CreatedUtcTime < dateadd(minute, -10, GetUtcDate())"; return(_connectionFactory().WithinTransaction(tx => TplHelper.Using(new SqlCommand(sql, tx.Connection, tx), cmd => cmd.ExecuteNonQueryAsync().Success(_ => tx.Commit()) ) ).Catch(_logger)); }
public SqlCommandBus(Func <SqlConnection> connectionFactory) { _connectionFactory = connectionFactory; _messageAdded = new LazyPublisher <SqlCommandMessage>(observer => { var isDisposed = false; _pollDbTask = _pollDbTask.ContinueWith(t => TplHelper.DoWhile(() => PollDb(observer).ThenDelay(PollDbInterval), _ => !isDisposed)).Unwrap(); _dbGcTask = _dbGcTask.ContinueWith(t => TplHelper.DoWhile(() => DbGc().ThenDelay(DbGcInterval), _ => !isDisposed)).Unwrap(); return(Disposable.Create(() => isDisposed = true)); }); }
static void SetStatusText([NotNull] IMainWindowViewModel mainWindowViewModel, [NotNull] string statusText) { if (mainWindowViewModel == null) { throw new ArgumentNullException(nameof(mainWindowViewModel)); } if (statusText == null) { throw new ArgumentNullException(nameof(statusText)); } // Do not invoke logging inside this method because the logger is forwarded. // Circular invocation -> Stack overflow! TplHelper.RunSync(() => mainWindowViewModel.SetStatusTextAsync(statusText)); }
public virtual Task Consumed(CommandMessage last) { var msg = last as SqlCommandMessage; if (msg == null) { return(TplHelper.Empty); } const string sql = "delete SheepJaxMessages where ClientId=@clientId and timestamp<@timestamp"; var dbTask = _connectionFactory().WithinTransaction(tx => TplHelper.Using(new SqlCommand(sql, tx.Connection, tx) { Parameters = { new SqlParameter("clientId", msg.ClientId), new SqlParameter("timestamp", msg.Timestamp) } } , cmd => cmd.ExecuteNonQueryAsync().Finally(_ => tx.Commit()) ) ).Catch(_logger); using (_cacheLock.BeginUpgradeableReadLock()) { var node = _cache.Last; while (node != null && node.Value != last) { node = node.Previous; } using (_cacheLock.BeginWriteLock()) { while (node != null) { var previousNode = node.Previous; while (previousNode != null && previousNode.Value.ClientId != node.Value.ClientId) { previousNode = previousNode.Previous; } node.List.Remove(node); node = previousNode; } } } return(dbTask); }
public static Task WithinTransaction(this SqlConnection conn, Func <SqlTransaction, Task> task) { SqlTransaction tx = null; try { conn.Open(); tx = conn.BeginTransaction(); return(task(tx).Finally(t => { tx.Dispose(); conn.Dispose(); })); } catch (Exception e) { if (tx != null) { tx.Dispose(); } conn.Dispose(); return(TplHelper.FromException(e)); } }
private void SendMessage(Guid clientId, string msg) { const string sql = "insert into SheepJaxMessages (ClientId, Message) values (@clientId, @message)"; Task.Factory.StartNew(delegate { _connectionFactory().WithinTransaction(tx => TplHelper.Using(new SqlCommand(sql, tx.Connection, tx) { Parameters = { new SqlParameter("clientId", clientId), new SqlParameter("message", msg) } }, cmd => cmd.ExecuteNonQueryAsync().Finally(t => tx.Commit()) ) ); }).Catch(_logger); }
protected virtual Task PollDb(IObserver <SqlCommandMessage> observer) { const string sql = "select ClientId, Message, CreatedUtcTime, Timestamp from SheepJaxMessages where CreatedUtcTime > dateadd(minute, -10, GetUtcDate())"; return(_connectionFactory().WithinTransaction(tx => TplHelper.Using(new SqlCommand(sql, tx.Connection, tx), cmd => { if (_lastTimestamp != null) { cmd.CommandText += " and timestamp > @lastTimestamp"; cmd.Parameters.Add(new SqlParameter("lastTimestamp", _lastTimestamp)); } cmd.CommandText += " order by timestamp asc"; return cmd.ExecuteReaderAsync() .Select(reader => { using (reader) while (reader.Read()) { var timestamp = _lastTimestamp = new byte[8]; reader.GetBytes(3, 0, timestamp, 0, 8); var msg = new SqlCommandMessage { ClientId = reader.GetGuid(0), Message = reader.GetString(1), CreatedUtcTime = reader.GetDateTime(2), Timestamp = timestamp }; using (_cacheLock.BeginWriteLock()) { _cache.AddLast(msg); observer.OnNext(msg); } } }); }) ).Catch(_logger)); }
public DateTime?NowUtc(TimeSpan timeout = default) { return(TplHelper.RunSync(() => NowUtcAsync(timeout))); }
public DateTime?NowUtc(string server, int port = 123, TimeSpan timeout = default) { return(TplHelper.RunSync(() => NowUtcAsync(server, port, timeout))); }
public async Task TestInstallAsync() { var snapAppsReleases = new SnapAppsReleases(); var genesisSnapApp = _baseFixture.BuildSnapApp(); Assert.True(genesisSnapApp.Channels.Count >= 2); await using var testDirectory = new DisposableDirectory(_baseFixture.WorkingDirectory, _snapFilesystem); using var genesisSnapReleaseBuilder = _baseFixture.WithSnapReleaseBuilder(testDirectory, snapAppsReleases, genesisSnapApp, _snapReleaseBuilderContext); var mainAssemblyDefinition = _baseFixture.BuildSnapExecutable(genesisSnapApp); genesisSnapReleaseBuilder .AddNuspecItem(mainAssemblyDefinition) .AddNuspecItem(mainAssemblyDefinition.BuildRuntimeConfigFilename(_snapFilesystem), mainAssemblyDefinition.BuildRuntimeConfig()) .AddNuspecItem(_baseFixture.BuildLibrary("test1")) .AddSnapDll(); using var genesisPackageContext = await _baseFixture.BuildPackageAsync(genesisSnapReleaseBuilder); var loggerMock = new Mock <ILog>(); var progressSource = new Mock <ISnapProgressSource>(); progressSource. Setup(x => x.Raise(It.IsAny <int>())); var snapOsProcessManager = new Mock <ISnapOsProcessManager>(); snapOsProcessManager .Setup(x => x.RunAsync(It.IsAny <ProcessStartInfoBuilder>(), It.IsAny <CancellationToken>())) .ReturnsAsync((ProcessStartInfoBuilder builder, CancellationToken cancellationToken) => { var result = TplHelper.RunSync(() => _snapOsProcessManager.RunAsync(builder, cancellationToken)); return(result); }); snapOsProcessManager .Setup(x => x.StartNonBlocking(It.IsAny <ProcessStartInfoBuilder>())) .Returns((ProcessStartInfoBuilder builder) => _snapOsProcessManager.StartNonBlocking(builder)); snapOsProcessManager .Setup(x => x.ChmodExecuteAsync(It.IsAny <string>(), It.IsAny <CancellationToken>())) .Returns((string filename, CancellationToken cancellationToken) => _snapOsProcessManager.ChmodExecuteAsync(filename, cancellationToken)); _snapOsMock .Setup(x => x.Filesystem) .Returns(_snapFilesystem); _snapOsMock .Setup(x => x.ProcessManager) .Returns(snapOsProcessManager.Object); _snapOsMock .Setup(x => x.CreateShortcutsForExecutableAsync( It.IsAny <SnapOsShortcutDescription>(), It.IsAny <ILog>(), It.IsAny <CancellationToken>())) .Returns(Task.CompletedTask); await using var baseDirectory = _baseFixture.WithDisposableTempDirectory(_snapFilesystem); using var installCts = new CancellationTokenSource(); var snapCurrentChannel = genesisPackageContext.FullPackageSnapApp.GetCurrentChannelOrThrow(); await _snapInstaller.InstallAsync( genesisPackageContext.FullPackageAbsolutePath, baseDirectory.WorkingDirectory, genesisPackageContext.FullPackageSnapRelease, snapCurrentChannel, progressSource.Object, loggerMock.Object, cancellationToken : installCts.Token); var appDirectory = _snapFilesystem.PathCombine(baseDirectory.WorkingDirectory, $"app-{genesisPackageContext.FullPackageSnapApp.Version}"); var snapAppUpdated = appDirectory.GetSnapAppFromDirectory(_snapFilesystem, _snapAppReader); var snapAppUpdatedChannel = snapAppUpdated.GetCurrentChannelOrThrow(); Assert.Equal(snapCurrentChannel.Name, snapAppUpdatedChannel.Name); var coreRunExe = _snapFilesystem.PathCombine(baseDirectory.WorkingDirectory, _snapEmbeddedResources.GetCoreRunExeFilenameForSnapApp(genesisPackageContext.FullPackageSnapApp)); var appExe = _snapFilesystem.PathCombine(baseDirectory.WorkingDirectory, $"app-{genesisSnapReleaseBuilder.SnapApp.Version}", genesisSnapReleaseBuilder.CoreRunExe); var snapInstalledArguments = $"--snapx-installed {genesisPackageContext.FullPackageSnapApp.Version.ToNormalizedString()}"; var snapFirstRunArguments = $"--snapx-first-run {genesisPackageContext.FullPackageSnapApp.Version.ToNormalizedString()}"; progressSource.Verify(x => x.Raise(It.Is <int>(v => v == 100)), Times.Once); if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { snapOsProcessManager.Verify(x => x.ChmodExecuteAsync( It.IsAny <string>(), It.IsAny <CancellationToken>()), Times.Exactly(2)); snapOsProcessManager.Verify(x => x.ChmodExecuteAsync( It.Is <string>(v => v == coreRunExe), It.Is <CancellationToken>(v => v == installCts.Token)), Times.Once); snapOsProcessManager.Verify(x => x.ChmodExecuteAsync( It.Is <string>(v => v == appExe), It.Is <CancellationToken>(v => v == installCts.Token)), Times.Once); } _snapOsMock.Verify(x => x.KillAllProcessesInsideDirectory( It.Is <string>(v => v == baseDirectory.WorkingDirectory)), Times.Once); _snapOsMock.Verify(x => x.CreateShortcutsForExecutableAsync( It.IsAny <SnapOsShortcutDescription>(), It.IsAny <ILog>(), It.IsAny <CancellationToken>()), Times.Once); _snapOsMock.Verify(x => x.CreateShortcutsForExecutableAsync( It.Is <SnapOsShortcutDescription>(v => v.ExeAbsolutePath == coreRunExe), It.Is <ILog>(v => v != null), It.Is <CancellationToken>(v => v == installCts.Token)), Times.Once); snapOsProcessManager.Verify(x => x.RunAsync( It.IsAny <ProcessStartInfoBuilder>(), It.IsAny <CancellationToken>()), Times.Once); snapOsProcessManager.Verify(x => x.RunAsync( It.Is <ProcessStartInfoBuilder>(v => v.Filename == appExe && v.Arguments == snapInstalledArguments), It.Is <CancellationToken>(v => v == installCts.Token)), Times.Once); snapOsProcessManager.Verify(x => x.StartNonBlocking( It.Is <ProcessStartInfoBuilder>(v => v.Filename == appExe & v.Arguments == snapFirstRunArguments)), Times.Once); snapOsProcessManager.Verify(x => x.StartNonBlocking( It.IsAny <ProcessStartInfoBuilder>()), Times.Once); }
public async Task TestUpdateAsync() { var snapAppsReleases = new SnapAppsReleases(); var genesisSnapApp = _baseFixture.BuildSnapApp(); var update1SnapApp = _baseFixture.Bump(genesisSnapApp); var update2SnapApp = _baseFixture.Bump(update1SnapApp); await using var testDirectory = new DisposableDirectory(_baseFixture.WorkingDirectory, _snapFilesystem); using var genesisSnapReleaseBuilder = _baseFixture.WithSnapReleaseBuilder(testDirectory, snapAppsReleases, genesisSnapApp, _snapReleaseBuilderContext); using var update1SnapReleaseBuilder = _baseFixture.WithSnapReleaseBuilder(testDirectory, snapAppsReleases, update1SnapApp, _snapReleaseBuilderContext); using var update2SnapReleaseBuilder = _baseFixture.WithSnapReleaseBuilder(testDirectory, snapAppsReleases, update2SnapApp, _snapReleaseBuilderContext); var mainExecutable = _baseFixture.BuildSnapExecutable(genesisSnapApp); genesisSnapReleaseBuilder .AddNuspecItem(mainExecutable) .AddNuspecItem(mainExecutable.BuildRuntimeConfigFilename(_snapFilesystem), mainExecutable.BuildRuntimeConfig()) .AddNuspecItem(_baseFixture.BuildLibrary("test1")) .AddSnapDll(); update1SnapReleaseBuilder .AddNuspecItem(genesisSnapReleaseBuilder, 0) .AddNuspecItem(genesisSnapReleaseBuilder, 1) .AddNuspecItem(genesisSnapReleaseBuilder, 2) .AddNuspecItem(_baseFixture.BuildLibrary("test2")) .AddSnapDll(); update2SnapReleaseBuilder .AddNuspecItem(update1SnapReleaseBuilder, 0) .AddNuspecItem(update1SnapReleaseBuilder, 1) .AddNuspecItem(update1SnapReleaseBuilder, 2) .AddNuspecItem(update1SnapReleaseBuilder, 3) .AddNuspecItem(_baseFixture.BuildLibrary("test3")) .AddSnapDll(); using var genesisPackageContext = await _baseFixture.BuildPackageAsync(genesisSnapReleaseBuilder); using (await _baseFixture.BuildPackageAsync(update1SnapReleaseBuilder)) { using var update2PackageContext = await _baseFixture.BuildPackageAsync(update2SnapReleaseBuilder); var loggerMock = new Mock <ILog>(); var progressSource = new Mock <ISnapProgressSource>(); progressSource. Setup(x => x.Raise(It.IsAny <int>())); var snapOsProcessManager = new Mock <ISnapOsProcessManager>(); snapOsProcessManager .Setup(x => x.RunAsync(It.IsAny <ProcessStartInfoBuilder>(), It.IsAny <CancellationToken>())) .ReturnsAsync((ProcessStartInfoBuilder builder, CancellationToken cancellationToken) => { var result = TplHelper.RunSync(() => _snapOsProcessManager.RunAsync(builder, cancellationToken)); return(result); }); snapOsProcessManager .Setup(x => x.StartNonBlocking(It.IsAny <ProcessStartInfoBuilder>())) .Returns((ProcessStartInfoBuilder builder) => _snapOsProcessManager.StartNonBlocking(builder)); snapOsProcessManager .Setup(x => x.ChmodExecuteAsync(It.IsAny <string>(), It.IsAny <CancellationToken>())) .Returns((string filename, CancellationToken cancellationToken) => _snapOsProcessManager.ChmodExecuteAsync(filename, cancellationToken)); _snapOsMock .Setup(x => x.Filesystem) .Returns(_snapFilesystem); _snapOsMock .Setup(x => x.ProcessManager) .Returns(snapOsProcessManager.Object); _snapOsMock .Setup(x => x.CreateShortcutsForExecutableAsync( It.IsAny <SnapOsShortcutDescription>(), It.IsAny <ILog>(), It.IsAny <CancellationToken>())) .Returns(Task.CompletedTask); await using var baseDirectory = _baseFixture.WithDisposableTempDirectory(_snapFilesystem); using var updateCts = new CancellationTokenSource(); await _snapInstaller.InstallAsync( genesisPackageContext.FullPackageAbsolutePath, baseDirectory.WorkingDirectory, genesisPackageContext.FullPackageSnapRelease, genesisPackageContext.FullPackageSnapApp.GetCurrentChannelOrThrow(), cancellationToken : updateCts.Token); _snapOsMock.Invocations.Clear(); snapOsProcessManager.Invocations.Clear(); var update2FullNupkgAbsolutePath = _snapFilesystem.PathCombine(baseDirectory.WorkingDirectory, "packages", update2PackageContext.FullPackageSnapRelease.BuildNugetFilename()); await _snapFilesystem.FileCopyAsync(update2PackageContext.FullPackageAbsolutePath, update2FullNupkgAbsolutePath, default); await _snapInstaller.UpdateAsync( baseDirectory.WorkingDirectory, update2PackageContext.FullPackageSnapRelease, update2PackageContext.FullPackageSnapApp.GetCurrentChannelOrThrow(), progressSource.Object, loggerMock.Object, updateCts.Token); var coreRunExe = _snapFilesystem.PathCombine(baseDirectory.WorkingDirectory, update2SnapReleaseBuilder.CoreRunExe); var appExe = _snapFilesystem.PathCombine(baseDirectory.WorkingDirectory, $"app-{update2SnapReleaseBuilder.SnapApp.Version}", update2SnapReleaseBuilder.CoreRunExe); var snapUpdatedArguments = $"--snapx-updated {update2SnapReleaseBuilder.SnapApp.Version.ToNormalizedString()}"; progressSource.Verify(x => x.Raise(It.Is <int>(v => v == 100)), Times.Once); if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { snapOsProcessManager.Verify(x => x.ChmodExecuteAsync( It.IsAny <string>(), It.IsAny <CancellationToken>()), Times.Exactly(2)); snapOsProcessManager.Verify(x => x.ChmodExecuteAsync( It.Is <string>(v => v == coreRunExe), It.Is <CancellationToken>(v => v == updateCts.Token)), Times.Once); snapOsProcessManager.Verify(x => x.ChmodExecuteAsync( It.Is <string>(v => v == appExe), It.Is <CancellationToken>(v => v == updateCts.Token)), Times.Once); } _snapOsMock.Verify(x => x.KillAllProcessesInsideDirectory( It.IsAny <string>()), Times.Never); _snapOsMock.Verify(x => x.CreateShortcutsForExecutableAsync( It.IsAny <SnapOsShortcutDescription>(), It.IsAny <ILog>(), It.IsAny <CancellationToken>()), Times.Once); _snapOsMock.Verify(x => x.CreateShortcutsForExecutableAsync( It.Is <SnapOsShortcutDescription>(v => v.ExeAbsolutePath == coreRunExe), It.Is <ILog>(v => v != null), It.Is <CancellationToken>(v => v == updateCts.Token)), Times.Once); snapOsProcessManager.Verify(x => x.RunAsync(It.Is <ProcessStartInfoBuilder>( v => v.Filename == appExe && v.Arguments == snapUpdatedArguments), It.Is <CancellationToken>(v => v == updateCts.Token)), Times.Once); snapOsProcessManager.Verify(x => x.StartNonBlocking(It.IsAny <ProcessStartInfoBuilder>()), Times.Never); } }
public async Task TestInstallAsync_Different_Channel() { var snapAppsReleases = new SnapAppsReleases(); var genesisSnapApp = _baseFixture.BuildSnapApp(); Assert.True(genesisSnapApp.Channels.Count >= 2); await using var testDirectory = new DisposableDirectory(_baseFixture.WorkingDirectory, _snapFilesystem); using var genesisSnapReleaseBuilder = _baseFixture.WithSnapReleaseBuilder(testDirectory, snapAppsReleases, genesisSnapApp, _snapReleaseBuilderContext); var mainAssemblyDefinition = _baseFixture.BuildSnapExecutable(genesisSnapApp); genesisSnapReleaseBuilder .AddNuspecItem(mainAssemblyDefinition) .AddSnapDll(); using var genesisPackageContext = await _baseFixture.BuildPackageAsync(genesisSnapReleaseBuilder); var loggerMock = new Mock <ILog>(); var snapOsProcessManager = new Mock <ISnapOsProcessManager>(); snapOsProcessManager .Setup(x => x.RunAsync(It.IsAny <ProcessStartInfoBuilder>(), It.IsAny <CancellationToken>())) .ReturnsAsync((ProcessStartInfoBuilder builder, CancellationToken cancellationToken) => { var result = TplHelper.RunSync(() => _snapOsProcessManager.RunAsync(builder, cancellationToken)); return(result); }); snapOsProcessManager .Setup(x => x.StartNonBlocking(It.IsAny <ProcessStartInfoBuilder>())) .Returns((ProcessStartInfoBuilder builder) => _snapOsProcessManager.StartNonBlocking(builder)); snapOsProcessManager .Setup(x => x.ChmodExecuteAsync(It.IsAny <string>(), It.IsAny <CancellationToken>())) .Returns((string filename, CancellationToken cancellationToken) => _snapOsProcessManager.ChmodExecuteAsync(filename, cancellationToken)); _snapOsMock .Setup(x => x.Filesystem) .Returns(_snapFilesystem); _snapOsMock .Setup(x => x.ProcessManager) .Returns(snapOsProcessManager.Object); _snapOsMock .Setup(x => x.CreateShortcutsForExecutableAsync( It.IsAny <SnapOsShortcutDescription>(), It.IsAny <ILog>(), It.IsAny <CancellationToken>())) .Returns(Task.CompletedTask); await using var baseDirectory = _baseFixture.WithDisposableTempDirectory(_snapFilesystem); using var installCts = new CancellationTokenSource(); var nextSnapChannel = genesisSnapApp.GetNextChannel(); await _snapInstaller.InstallAsync( genesisPackageContext.FullPackageAbsolutePath, baseDirectory.WorkingDirectory, genesisPackageContext.FullPackageSnapRelease, nextSnapChannel, null, loggerMock.Object, cancellationToken : installCts.Token); var appDirectory = _snapFilesystem.PathCombine(baseDirectory.WorkingDirectory, $"app-{genesisPackageContext.FullPackageSnapApp.Version}"); var snapAppUpdated = appDirectory.GetSnapAppFromDirectory(_snapFilesystem, _snapAppReader); var snapAppUpdatedChannel = snapAppUpdated.GetCurrentChannelOrThrow(); Assert.Equal(nextSnapChannel.Name, snapAppUpdatedChannel.Name); }
static async Task <(int exitCode, SnapInstallerType installerType)> MainImplAsync([NotNull] ISnapInstallerEnvironment snapInstallerEnvironment, [NotNull] ILog snapInstallerLogger, bool headless) { if (snapInstallerEnvironment == null) { throw new ArgumentNullException(nameof(snapInstallerEnvironment)); } if (snapInstallerLogger == null) { throw new ArgumentNullException(nameof(snapInstallerLogger)); } var snapOs = snapInstallerEnvironment.Container.GetInstance <ISnapOs>(); var snapEmbeddedResources = snapInstallerEnvironment.Container.GetInstance <ISnapEmbeddedResources>(); var snapCryptoProvider = snapInstallerEnvironment.Container.GetInstance <ISnapCryptoProvider>(); var thisExeWorkingDirectory = snapInstallerEnvironment.Io.ThisExeWorkingDirectory; var workingDirectory = snapInstallerEnvironment.Io.WorkingDirectory; TplHelper.RunSync(() => snapEmbeddedResources.ExtractCoreRunLibAsync(snapOs.Filesystem, snapCryptoProvider, thisExeWorkingDirectory, snapOs.OsPlatform)); var coreRunLib = new CoreRunLib(snapOs.Filesystem, snapOs.OsPlatform, thisExeWorkingDirectory); var snapInstaller = snapInstallerEnvironment.Container.GetInstance <ISnapInstaller>(); var snapInstallerEmbeddedResources = snapInstallerEnvironment.Container.GetInstance <ISnapInstallerEmbeddedResources>(); var snapPack = snapInstallerEnvironment.Container.GetInstance <ISnapPack>(); var snapAppReader = snapInstallerEnvironment.Container.GetInstance <ISnapAppReader>(); var snapAppWriter = snapInstallerEnvironment.Container.GetInstance <ISnapAppWriter>(); var snapFilesystem = snapInstallerEnvironment.Container.GetInstance <ISnapFilesystem>(); snapFilesystem.DirectoryCreateIfNotExists(snapOs.SpecialFolders.InstallerCacheDirectory); var snapPackageManager = snapInstallerEnvironment.Container.GetInstance <ISnapPackageManager>(); var snapExtractor = snapInstallerEnvironment.Container.GetInstance <ISnapExtractor>(); var nugetServiceCommandInstall = new NugetService(snapOs.Filesystem, new NugetLogger(snapInstallerLogger)); Task <(int exitCode, SnapInstallerType installerType)> RunInstallerAsync() { return(InstallAsync(snapInstallerEnvironment, snapInstallerEmbeddedResources, snapInstaller, snapFilesystem, snapPack, snapOs, coreRunLib, snapAppReader, snapAppWriter, nugetServiceCommandInstall, snapPackageManager, snapExtractor, snapInstallerLogger, headless)); } try { var mutexName = snapCryptoProvider.Sha256(Encoding.UTF8.GetBytes(workingDirectory)); _mutexSingleInstanceWorkingDirectory = new Mutex(true, $"Global\\{mutexName}", out var createdNew); if (!createdNew) { snapInstallerLogger.Error("Setup is already running, exiting..."); return(1, SnapInstallerType.None); } _mutexIsTaken = true; } catch (Exception e) { snapInstallerLogger.ErrorException("Error creating installer mutex, exiting...", e); return(1, SnapInstallerType.None); } return(await RunInstallerAsync()); }