diff --git a/src/TwitchStreamingTools/Program.cs b/src/TwitchStreamingTools/Program.cs
index f7e7589..d0b296d 100644
--- a/src/TwitchStreamingTools/Program.cs
+++ b/src/TwitchStreamingTools/Program.cs
@@ -1,6 +1,7 @@
using System;
using System.IO;
using System.Runtime.Versioning;
+using System.Threading;
using Avalonia;
using Avalonia.ReactiveUI;
@@ -13,14 +14,24 @@
namespace TwitchStreamingTools;
internal sealed class Program {
+ // Initialization code. Don't use any Avalonia, third-party APIs or any
+ // SynchronizationContext-reliant code before AppMain is called: things aren't initialized
+ // yet and stuff might break.
+
+ ///
+ /// The name used to ensure only a single instance of the application is running.
+ ///
+ private const string MutexName = "TwitchStreamingTools_SingleInstance";
+
///
/// The logger.
///
private static readonly ILog Log = LogManager.GetLogger(typeof(Program));
- // Initialization code. Don't use any Avalonia, third-party APIs or any
- // SynchronizationContext-reliant code before AppMain is called: things aren't initialized
- // yet and stuff might break.
+ ///
+ /// Used to prevent multiple instances of the application from running.
+ ///
+ private static Mutex? _mutex;
///
/// Main entrypoint of the application.
@@ -31,7 +42,7 @@ public static void Main(string[] args) {
#if DEBUG
XmlConfigurator.Configure(new FileInfo("log4net.debug.config"));
#else
- XmlConfigurator.Configure(new FileInfo("log4net.config"));
+ XmlConfigurator.Configure(new FileInfo("log4net.config"));
#endif
Log.Info("Started application");
@@ -40,11 +51,24 @@ public static void Main(string[] args) {
Log.Fatal("Unhandled exception", exceptArgs.ExceptionObject as Exception);
};
- BuildAvaloniaApp()
- .StartWithClassicDesktopLifetime(args);
- }
+ // We only allow a single instance of the application to be launched at once (due to having only a single config
+ // file)
+ _mutex = new Mutex(true, MutexName, out bool onlyAppInstance);
+ if (!onlyAppInstance) {
+ Log.Info("Application instance already running. Exiting.");
+ return;
+ }
- // Avalonia configuration, don't remove; also used by visual designer.
+ try {
+ BuildAvaloniaApp()
+ .StartWithClassicDesktopLifetime(args);
+ }
+ finally {
+ // Release the mutex when the application exits
+ _mutex.ReleaseMutex();
+ _mutex.Dispose();
+ }
+ }
///
/// Builds the avalonia application.
diff --git a/src/TwitchStreamingTools/TwitchStreamingTools.csproj.DotSettings b/src/TwitchStreamingTools/TwitchStreamingTools.csproj.DotSettings
index 4527ed0..d0d789b 100644
--- a/src/TwitchStreamingTools/TwitchStreamingTools.csproj.DotSettings
+++ b/src/TwitchStreamingTools/TwitchStreamingTools.csproj.DotSettings
@@ -1,4 +1,5 @@
-
Library
\ No newline at end of file