Example #1
0
        /// <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);
                }
            }));
        }
Example #2
0
        /// <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);
            }
        }
Example #3
0
    /// <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();
            }
        }));
    }
Example #4
0
    public override ProcessStartInfo GetStartInfo(params string[] arguments)
    {
        if (AppMutex.Probe(_updateMutexName) || AppMutex.Probe(_legacyUpdateMutexName))
        {
            throw new TemporarilyUnavailableException();
        }

        return(base.GetStartInfo(arguments));
    }
Example #5
0
        /// <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
            }
        }
Example #6
0
        /// <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);
        }
Example #7
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;
    }
Example #8
0
        /// <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);
            }
        }
Example #9
0
        /// <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();
        }