/// <summary> /// Common initialization code to be called by every Frontend executable right after startup. /// </summary> public static void Init() { // Encode installation path into mutex name to allow instance detection during updates string mutexName = "mutex-" + Locations.InstallBase.GetHashCode(); if (AppMutex.Probe(mutexName + "-update")) { Environment.Exit(999); } AppMutex.Create(mutexName); if (WindowsUtils.IsWindows && !Locations.IsPortable && !StoreUtils.PathInAStore(Locations.InstallBase)) { try { RegistryUtils.SetSoftwareString("Zero Install", "InstallLocation", Locations.InstallBase); RegistryUtils.SetSoftwareString(@"Microsoft\PackageManagement", "ZeroInstall", Path.Combine(Locations.InstallBase, "ZeroInstall.OneGet.dll")); } catch (IOException) {} catch (UnauthorizedAccessException) {} } NetUtils.ApplyProxy(); if (!WindowsUtils.IsWindows7) { NetUtils.TrustCertificates(SyncIntegrationManager.DefaultServerPublicKey); } }
/// <summary> /// Waits for any Zero Install instances running in <see cref="TargetDir"/> to terminate and then prevents new ones from starting. /// </summary> /// <remarks>The <see cref="TargetDir"/> is encoded into an <see cref="AppMutex"/> name using <see cref="object.GetHashCode"/>.</remarks> private void TargetMutexAquire() { if (TargetDir == Locations.InstallBase) { Log.Info("Cannot use Mutex because source and target directory are the same: " + TargetDir); return; } int hashCode = TargetDir.GetHashCode(); if (hashCode == Locations.InstallBase.GetHashCode()) { // Very unlikely but possible, since .GetHashCode() is not a cryptographic hash Log.Warn("Hash collision between " + TargetDir + " and " + Locations.InstallBase + "! Not using Mutex."); return; } string targetMutex = "mutex-" + hashCode; Handler.RunTask(new SimpleTask(Resources.MutexWait, () => { // Wait for existing instances to terminate while (AppMutex.Probe(targetMutex)) { Thread.Sleep(1000); } // Prevent new instances from starting AppMutex.Create(targetMutex + "-update", out _targetMutex); // Detect any new instances that started in the short time between detecting existing ones and blocking new ones while (AppMutex.Probe(targetMutex)) { Thread.Sleep(1000); } })); }
/// <summary> /// Waits for any Zero Install instances running in <see cref="TargetDir"/> to terminate and then prevents new ones from starting. /// </summary> /// <remarks>The <see cref="TargetDir"/> is encoded into an <see cref="AppMutex"/> name using <see cref="object.GetHashCode"/>.</remarks> private void MutexAcquire() { if (FileUtils.PathEquals(TargetDir, Locations.InstallBase)) { Log.Info("Cannot use Mutex because source and target directory are the same: " + TargetDir); return; } if (ZeroInstallEnvironment.MutexName(TargetDir) == ZeroInstallEnvironment.MutexName(Locations.InstallBase)) { Log.Warn($"Hash collision between {TargetDir} and {Locations.InstallBase}! Not using Mutex."); return; } Handler.RunTask(new SimpleTask(Resources.MutexWait, () => { // Wait for existing instances to terminate while (AppMutex.Probe(ZeroInstallEnvironment.MutexName(TargetDir)) || AppMutex.Probe(ZeroInstallEnvironment.LegacyMutexName(TargetDir))) { Thread.Sleep(1000); Handler.CancellationToken.ThrowIfCancellationRequested(); } // Prevent new instances from starting during the update _updateMutex = AppMutex.Create(ZeroInstallEnvironment.UpdateMutexName(TargetDir)); _legacyUpdateMutex = AppMutex.Create(ZeroInstallEnvironment.LegacyUpdateMutexName(TargetDir)); // Detect any new instances that started in the short time between detecting existing ones and blocking new ones while (AppMutex.Probe(ZeroInstallEnvironment.MutexName(TargetDir)) || AppMutex.Probe(ZeroInstallEnvironment.LegacyMutexName(TargetDir))) { Thread.Sleep(1000); Handler.CancellationToken.ThrowIfCancellationRequested(); } })); }
private static void Main(string[] args) { WindowsUtils.SetCurrentProcessAppID(Application.CompanyName + "." + GeneralSettings.AppNameShort); Application.EnableVisualStyles(); ErrorReportForm.SetupMonitoring(new Uri("http://omegaengine.de/error-report/?app=" + GeneralSettings.AppNameShort)); #if !DEBUG // Prevent multiple instances from running simultaneously if (AppMutex.Create(GeneralSettings.AppName)) { Msg.Inform(null, Resources.AlreadyRunning, MsgSeverity.Warn); return; } #endif Args = new Arguments(args); Settings.LoadCurrent(); UpdateLocale(); Settings.SaveCurrent(); // Show additional warning before actually starting the game if (Args.Contains("launchWarn") && !Args.Contains("benchmark")) { if (!Msg.OkCancel(null, Resources.ReadyToLaunch, MsgSeverity.Info, Resources.ReadyToLaunchContinue)) { return; } } // Handle benchmark mode if (Args.Contains("benchmark")) { if (!Msg.OkCancel(null, Resources.BenchmarkInfo, MsgSeverity.Info, Resources.BenchmarkInfoContinue)) { return; } ConfigureSettingsForBenchmark(); } if (!DetermineContentDirs()) { return; } if (!LoadArchives()) { return; } using (var game = new Game()) game.Run(); ContentManager.CloseArchives(); }
/// <summary> /// The main entry point for the application. /// </summary> // NOTE: No [STAThread] here, because it could block .NET remoting private static int Main(string[] args) { // Encode installation path into mutex name to allow instance detection during updates string mutexName = "mutex-" + Locations.InstallBase.GetHashCode(); if (AppMutex.Probe(mutexName + "-update")) { return(999); } if (args == null || args.Length == 0) { // NOTE: Do not block updater from starting because it will automatically stop service ServiceBase.Run(new ServiceBase[] { new StoreService() }); return(0); } else { AppMutex.Create(mutexName); if (Locations.IsPortable) { Msg.Inform(null, Resources.NoPortableMode, MsgSeverity.Error); return(1); } string command = args[0].ToLowerInvariant(); bool silent = args.Contains("--silent", StringComparer.OrdinalIgnoreCase); try { return(HandleCommand(command, silent)); } #region Error handling catch (Win32Exception ex) { if (!silent) { Msg.Inform(null, ex.Message, MsgSeverity.Error); } return(1); } catch (InvalidOperationException ex) { if (!silent) { Msg.Inform(null, ex.Message, MsgSeverity.Error); } return(1); } #endregion } }
/// <summary> /// Common initialization code to be called by every Zero Install executable right after startup. /// </summary> public static void Init() { AppMutex.Create(ZeroInstallEnvironment.MutexName()); AppMutex.Create(ZeroInstallEnvironment.LegacyMutexName()); if (AppMutex.Probe(ZeroInstallEnvironment.UpdateMutexName()) || AppMutex.Probe(ZeroInstallEnvironment.LegacyUpdateMutexName())) { Environment.Exit(999); } if (UILanguage != null) { Languages.SetUI(UILanguage); } ProcessUtils.SanitizeEnvironmentVariables(); NetUtils.ApplyProxy(); ServicePointManager.DefaultConnectionLimit = 16; }
/// <summary> /// Waits for any Zero Install instances running in <see cref="Target"/> to terminate and then prevents new ones from starting. /// </summary> public void MutexAquire() { // Installation paths are encoded into mutex names to allow instance detection // Support old versions that used SHA256 or MD5 for mutex names string targetMutexOld1 = "mutex-" + Target.Hash(SHA256.Create()); string targetMutexOld2 = "mutex-" + Target.Hash(MD5.Create()); string targetMutex = "mutex-" + Target.GetHashCode(); // Wait for existing instances to terminate while (AppMutex.Probe(targetMutexOld1)) { Thread.Sleep(1000); } while (AppMutex.Probe(targetMutexOld2)) { Thread.Sleep(1000); } while (AppMutex.Probe(targetMutex)) { Thread.Sleep(1000); } // Prevent new instances from starting AppMutex.Create(targetMutexOld1 + "-update", out _blockingMutexOld); AppMutex.Create(targetMutexOld2 + "-update", out _blockingMutexOld); AppMutex.Create(targetMutex + "-update", out _blockingMutexNew); // Detect any new instances that started in the short time between detecting existing ones and blocking new ones while (AppMutex.Probe(targetMutexOld1)) { Thread.Sleep(1000); } while (AppMutex.Probe(targetMutexOld2)) { Thread.Sleep(1000); } while (AppMutex.Probe(targetMutex)) { Thread.Sleep(1000); } }
/// <summary> /// Common initialization code to be called by every Frontend executable right after startup. /// </summary> public static void Init() { // Encode installation path into mutex name to allow instance detection during updates string mutexName = "mutex-" + Locations.InstallBase.GetHashCode(); if (AppMutex.Probe(mutexName + "-update")) { Environment.Exit(999); } AppMutex.Create(mutexName); if (WindowsUtils.IsWindows && UILanguage != null) { Languages.SetUI(UILanguage); } if (!WindowsUtils.IsWindows7) { NetUtils.TrustCertificates(SyncIntegrationManager.DefaultServerPublicKey); } NetUtils.ApplyProxy(); }
public override string RunAndCapture(Action <StreamWriter>?onStartup, params string[] arguments) { using (AppMutex.Create(_mutexName)) using (AppMutex.Create(_legacyMutexName)) return(base.RunAndCapture(onStartup, arguments)); }
public override void Run(params string[] arguments) { using (AppMutex.Create(_mutexName)) using (AppMutex.Create(_legacyMutexName)) base.Run(arguments); }
private static void Main(string[] args) { WindowsUtils.SetCurrentProcessAppID(Application.CompanyName + "." + GeneralSettings.AppNameShort + ".AlphaEditor"); ModInfo.FileExt = "." + GeneralSettings.AppNameShort + "Mod"; Application.EnableVisualStyles(); ErrorReportForm.SetupMonitoring(new Uri("http://omegaengine.de/error-report/?app=" + GeneralSettings.AppNameShort)); // Allow setup to detect running instances AppMutex.Create(GeneralSettings.AppName + " Editor"); Args = new Arguments(args); Settings.LoadCurrent(); UpdateLocale(); Settings.SaveCurrent(); if (!DetermineContentDirs()) { return; } if (Settings.Current.Editor.ShowWelcomeMessage) { Restart = false; // Will be set to true again, if the user clicks "Continue" Application.Run(new WelcomeForm()); } // The user might want to come back here multiple times, in order to switch the mod while (Restart) { Restart = false; // Ask user to select mod, cancel if an exception occurred Application.Run(new ModSelectorForm(Settings.Current.Editor.EditBase, Settings.Current.Editor.RecentMods)); // Exit if the user didn't select anything if (ContentManager.ModDir == null && !ModInfo.MainGame) { break; } // Load the archives, run the main editor, cancel if an exception occurred, always unload the archives if (!LoadArchives()) { break; } try { Application.Run(new MainForm()); } finally { ContentManager.CloseArchives(); } // Prepare for next selection ModInfo.MainGame = false; ContentManager.ModDir = null; // After the MainForm has closed a lot of garbage will be left in Generation 2. // We should run Garbage Collection now, so we don't keep on wasting a large chunk of memory. GC.Collect(); } }