Ejemplo n.º 1
0
        /// <summary>Starts the installer program, when all presumtions are fullfilled.</summary>
        /// <param name="isAltaxoCurrentlyStarting">If set to <c>true</c>, Altaxo will be restarted after the installation is done.</param>
        /// <param name="commandLineArgs">Original command line arguments. Can be <c>null</c> when calling this function on shutdown.</param>
        /// <returns>True if the installer program was started. Then Altaxo have to be shut down immediately. Returns <c>false</c> if the installer program was not started.</returns>
        public bool Run(bool isAltaxoCurrentlyStarting, string[] commandLineArgs)
        {
            var updateSettings = Current.PropertyService.GetValue(Altaxo.Settings.AutoUpdateSettings.PropertyKeyAutoUpdate, Main.Services.RuntimePropertyKind.UserAndApplicationAndBuiltin, () => new Altaxo.Settings.AutoUpdateSettings());

            var installationRequested = (isAltaxoCurrentlyStarting && updateSettings.InstallAtStartup) || (!isAltaxoCurrentlyStarting && updateSettings.InstallAtShutdown);

            if (!installationRequested)
            {
                return(false);
            }

            bool loadUnstable = updateSettings.DownloadUnstableVersion;

            FileStream versionFileStream = null;
            FileStream packageStream     = null;

            // try to lock the version file in the download directory, thus no other process can modify it
            try
            {
                var downloadFolder  = PackageInfo.GetDownloadDirectory(loadUnstable);
                var versionFileName = Path.Combine(downloadFolder, PackageInfo.VersionFileName);

                versionFileStream = new FileStream(versionFileName, FileMode.Open, FileAccess.Read, FileShare.Read);

                var info = PackageInfo.GetPresentDownloadedPackage(versionFileStream, downloadFolder, out packageStream);

                if (null == info || null == packageStream)
                {
                    return(false);
                }

                var entryAssembly        = System.Reflection.Assembly.GetEntryAssembly();
                var entryAssemblyVersion = entryAssembly.GetName().Version;

                if (info.Version <= entryAssemblyVersion)
                {
                    return(false); // no need to update
                }
                if (updateSettings.ConfirmInstallation)
                {
                    var question = string.Format(
                        "A new Altaxo update is available (from current version {0} to new {1} version {2}).\r\n\r\n" +
                        "If you don't want to have auto updates, please deactivate them by choosing 'Tools'->'Options' menu in Altaxo.\r\n" +
                        "\r\n" +
                        "Do you want to update to {1} version {2} now?", entryAssemblyVersion, PackageInfo.GetStableIdentifier(info.IsUnstableVersion).ToLower(), info.Version);

                    if (false == Current.Gui.YesNoMessageBox(question, "Altaxo update available", true))
                    {
                        return(false); // user don't want to update
                    }
                }

                // copy the Updater executable to the download folder
                var entryAssemblyFolder   = Path.GetDirectoryName(entryAssembly.Location);
                var installerFullSrcName  = Path.Combine(entryAssemblyFolder, UpdateInstallerFileName);
                var installerFullDestName = Path.Combine(downloadFolder, UpdateInstallerFileName);
                File.Copy(installerFullSrcName, installerFullDestName, true);

                // both the version file and the package stream are locked now
                // so we can start the updater program

                var eventName = System.Guid.NewGuid().ToString();
                var waitForRemoteStartSignal = new System.Threading.EventWaitHandle(false, System.Threading.EventResetMode.ManualReset, eventName);

                var processInfo = new System.Diagnostics.ProcessStartInfo
                {
                    FileName = installerFullDestName
                };
                var stb = new StringBuilder();
                stb.AppendFormat(System.Globalization.CultureInfo.InvariantCulture,
                                 "\"{0}\"\t\"{1}\"\t{2}\t{3}\t{4}\t\"{5}\"",
                                 eventName,
                                 packageStream.Name,
                                 updateSettings.ShowInstallationWindow ? 1 : 0,
                                 updateSettings.InstallationWindowClosingTime,
                                 isAltaxoCurrentlyStarting ? 1 : 0,
                                 entryAssembly.Location);
                if (isAltaxoCurrentlyStarting && commandLineArgs != null && commandLineArgs.Length > 0)
                {
                    foreach (var s in commandLineArgs)
                    {
                        stb.AppendFormat("\t\"{0}\"", s);
                    }
                }
                processInfo.Arguments      = stb.ToString();
                processInfo.CreateNoWindow = false;
                processInfo.WindowStyle    = System.Diagnostics.ProcessWindowStyle.Normal;

                // Start the updater program
                var process = System.Diagnostics.Process.Start(processInfo);

                for (; ;)
                {
                    // we wait until the update program signals that it has now taken the VersionInfo file
                    if (waitForRemoteStartSignal.WaitOne(100))
                    {
                        break;
                    }
                    if (process.HasExited)
                    {
                        return(false); // then something has gone wrong or the user has closed the window
                    }
                }

                return(true);
            }
            catch (Exception)
            {
                return(false);
            }
            finally
            {
                if (null != packageStream)
                {
                    packageStream.Close();
                }
                if (null != versionFileStream)
                {
                    versionFileStream.Close();
                }
            }
        }
Ejemplo n.º 2
0
        /// <summary>Runs the <see cref="Downloader"/>.</summary>
        /// <remarks>
        /// The download is done in steps:
        /// <para>Firstly, the appropriate version file in the application data directory is locked,
        /// so that no other program can use it, until this program ends.</para>
        /// <para>Then, the version file is downloaded from the remote location.</para>
        /// <para>If there is already a valid version file in the download directory,
        /// and the version obtained from the remote version file is equal to the version obtained from the version file in the download directory,
        /// then the package was already downloaded before. Then we only check that the package file is also present and that it has the appropriate hash sum.</para>
        /// <para>Else, if the version obtained from the remote version file is higher than the program's current version,
        /// we download the package file from the remote location.</para>
        /// </remarks>
        public void Run()
        {
            if (!Directory.Exists(_storagePath))
            {
                Directory.CreateDirectory(_storagePath);
                SetDownloadDirectoryAccessRights(_storagePath);
            }

            var versionFileFullName = Path.Combine(_storagePath, PackageInfo.VersionFileName);

            using (var fs = new FileStream(versionFileFullName, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None))
            {
                fs.Seek(0, SeekOrigin.Begin);
                var alreadyDownloadedVersion = PackageInfo.GetPresentDownloadedPackage(fs, _storagePath);
                fs.Seek(0, SeekOrigin.Begin);

                using (var webClient = new System.Net.WebClient())
                {
                    Console.Write("Starting to download version file ...");
                    var versionData = webClient.DownloadData(_downloadURL + PackageInfo.VersionFileName);
                    Console.WriteLine(" ok! ({0} bytes downloaded)", versionData.Length);
                    // we leave the file open, thus no other process can access it
                    var parsedVersions = PackageInfo.FromStream(new MemoryStream(versionData));

                    fs.Write(versionData, 0, versionData.Length);
                    fs.Flush(); // write the new version to disc in order to change the write date

                    // from all parsed versions, choose that one that matches the requirements
                    var parsedVersion = PackageInfo.GetHighestVersion(parsedVersions);

                    if (null != parsedVersion)
                    {
                        Console.WriteLine("The remote package version is: {0}", parsedVersion.Version);
                    }
                    else
                    {
                        Console.WriteLine("This computer does not match the requirements of any package. The version file contains {0} packages.", parsedVersions.Length);
                        return;
                    }

                    if (Comparer <Version> .Default.Compare(parsedVersion.Version, _currentVersion) > 0) // if the remote version is higher than the currently installed Altaxo version
                    {
                        Console.Write("Cleaning download directory ...");
                        CleanDirectory(versionFileFullName); // Clean old downloaded files from the directory
                        Console.WriteLine(" ok!");

                        var packageUrl      = _downloadURL + PackageInfo.GetPackageFileName(parsedVersion.Version);
                        var packageFileName = Path.Combine(_storagePath, PackageInfo.GetPackageFileName(parsedVersion.Version));
                        Console.WriteLine("Starting download of package file ...");
                        webClient.DownloadProgressChanged += EhDownloadOfPackageFileProgressChanged;
                        webClient.DownloadFileCompleted   += EhDownloadOfPackageFileCompleted;
                        _isDownloadOfPackageCompleted      = false;
                        webClient.DownloadFileAsync(new Uri(packageUrl), packageFileName);// download the package asynchronously to get progress messages
                        for (; !_isDownloadOfPackageCompleted;)
                        {
                            System.Threading.Thread.Sleep(250);
                        }
                        webClient.DownloadProgressChanged -= EhDownloadOfPackageFileProgressChanged;
                        webClient.DownloadFileCompleted   -= EhDownloadOfPackageFileCompleted;

                        Console.WriteLine("Download finished!");

                        // make at least the test for the right length
                        var fileInfo = new FileInfo(packageFileName);
                        if (fileInfo.Length != parsedVersion.FileLength)
                        {
                            Console.WriteLine("Downloaded file length ({0}) differs from length in VersionInfo.txt {1}, thus the downloaded file will be deleted!", fileInfo.Length, parsedVersion.FileLength);
                            fileInfo.Delete();
                        }
                        else
                        {
                            Console.WriteLine("Test file length of downloaded package file ... ok!");
                        }
                    }
                }
            }
        }