From 7d9e73f9caea1adaf1896da44976e399db03bd09 Mon Sep 17 00:00:00 2001 From: Student Main Date: Fri, 14 Aug 2020 17:03:22 +0800 Subject: [PATCH] go back to mutex based single instance for better reliability --- shadowsocks-csharp/Program.cs | 50 ++++++++++++++++++++++++----------- 1 file changed, 34 insertions(+), 16 deletions(-) diff --git a/shadowsocks-csharp/Program.cs b/shadowsocks-csharp/Program.cs index c05bb9cc..4fb8fbbf 100755 --- a/shadowsocks-csharp/Program.cs +++ b/shadowsocks-csharp/Program.cs @@ -20,6 +20,7 @@ namespace Shadowsocks internal static class Program { private static readonly Logger logger = LogManager.GetCurrentClassLogger(); + public static ShadowsocksController MainController { get; private set; } public static MenuViewController MenuController { get; private set; } public static CommandLineOption Options { get; private set; } @@ -28,6 +29,9 @@ namespace Shadowsocks // https://github.com/dotnet/runtime/issues/13051#issuecomment-510267727 public static readonly string ExecutablePath = Process.GetCurrentProcess().MainModule?.FileName; public static readonly string WorkingDirectory = Path.GetDirectoryName(ExecutablePath); + + private static readonly Mutex mutex = new Mutex(true, $"Shadowsocks_{ExecutablePath.GetHashCode()}"); + /// /// 应用程序的主入口点。 /// @@ -35,12 +39,33 @@ namespace Shadowsocks [STAThread] private static void Main(string[] args) { + #region Single Instance and IPC + bool hasAnotherInstance = !mutex.WaitOne(TimeSpan.Zero, true); + // store args for further use Args = args; Parser.Default.ParseArguments(args) .WithParsed(opt => Options = opt) .WithNotParsed(e => e.Output()); + if (hasAnotherInstance) + { + if (!string.IsNullOrWhiteSpace(Options.OpenUrl)) + { + IPCService.RequestOpenUrl(Options.OpenUrl); + } + else + { + MessageBox.Show(I18N.GetString("Find Shadowsocks icon in your notify tray.") + + Environment.NewLine + + I18N.GetString("If you want to start multiple Shadowsocks, make a copy in another directory."), + I18N.GetString("Shadowsocks is already running.")); + } + return; + } + #endregion + + #region Enviroment Setup Directory.SetCurrentDirectory(WorkingDirectory); // todo: initialize the NLog configuartion Model.NLogConfig.TouchAndApplyNLogConfig(); @@ -48,7 +73,9 @@ namespace Shadowsocks // .NET Framework 4.7.2 on Win7 compatibility ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12; + #endregion + #region Compactibility Check // Check OS since we are using dual-mode socket if (!Utils.IsWinVistaOrHigher()) { @@ -67,23 +94,9 @@ namespace Shadowsocks } return; } + #endregion - if (IPCService.AnotherInstanceRunning()) - { - if (!string.IsNullOrWhiteSpace(Options.OpenUrl)) - { - IPCService.RequestOpenUrl(Options.OpenUrl); - } - else - { - MessageBox.Show(I18N.GetString("Find Shadowsocks icon in your notify tray.") - + Environment.NewLine - + I18N.GetString("If you want to start multiple Shadowsocks, make a copy in another directory."), - I18N.GetString("Shadowsocks is already running.")); - } - return; - } - + #region Event Handlers Setup Utils.ReleaseMemory(true); Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException); @@ -96,6 +109,7 @@ namespace Shadowsocks Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); AutoStartup.RegisterForRestart(true); + #endregion #if DEBUG // truncate privoxy log file while debugging @@ -109,6 +123,7 @@ namespace Shadowsocks HotKeys.Init(MainController); MainController.Start(); + #region IPC Handler and Arguement Process IPCService ipcService = new IPCService(); Task.Run(() => ipcService.RunServer()); ipcService.OpenUrlRequested += (_1, e) => MainController.AskAddServerBySSURL(e.Url); @@ -117,7 +132,10 @@ namespace Shadowsocks { MainController.AskAddServerBySSURL(Options.OpenUrl); } + #endregion + Application.Run(); + } private static int exited = 0;