/// <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> /// 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 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(); } })); }
public override ProcessStartInfo GetStartInfo(params string[] arguments) { if (AppMutex.Probe(_updateMutexName) || AppMutex.Probe(_legacyUpdateMutexName)) { throw new TemporarilyUnavailableException(); } return(base.GetStartInfo(arguments)); }
/// <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> /// The main entry point for the application. /// </summary> // NOTE: No [STAThread] here, because it could block .NET remoting private static int Main() { // 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); } // NOTE: Do not block updater from starting because it will automatically stop service ServiceBase.Run(new ServiceBase[] { new StoreService() }); return(0); }
/// <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(); }