Beispiel #1
0
        /// <summary>If there already a package in the download directory, this function gets the present downloaded package. If anything is invalid (wrong format of the version file,
        /// wrong hash sum), the return value is <c>Null</c>.</summary>
        /// <param name="fs">Stream to read the version info from. This must be the opened stream of the VersionInfo.txt file in the download directory.</param>
        /// <param name="storagePath">Path to the directory that stores the downloaded package.</param>
        /// <param name="packageFile">On successfull return, the opened <see cref="FileStream"/> of the package file is provided here. You are responsible for closing the stream!</param>
        /// <returns>The info for the already present package in the download directory. If anything is invalid, the return value is null.</returns>
        public static PackageInfo GetPresentDownloadedPackage(Stream fs, string storagePath, out FileStream packageFile)
        {
            PackageInfo packageInfo = null;

            packageFile = null;
            try
            {
                var packageInfos = PackageInfo.FromStream(fs);
                packageInfo = PackageInfo.GetHighestVersion(packageInfos);

                // test, if the file exists and has the right Hash
                var fileInfo = new FileInfo(Path.Combine(storagePath, GetPackageFileName(packageInfo.Version)));
                if (!fileInfo.Exists)
                {
                    return(null);
                }

                // test for the appropriate length
                if (fileInfo.Length != packageInfo.FileLength)
                {
                    return(null);
                }

                packageFile = new FileStream(Path.Combine(storagePath, GetPackageFileName(packageInfo.Version)), FileMode.Open, FileAccess.Read, FileShare.Read);
                var hashProvider = new System.Security.Cryptography.SHA1Managed();
                var hash         = hashProvider.ComputeHash(packageFile);

                if (GetHashAsString(hash) != packageInfo.Hash)
                {
                    throw new InvalidOperationException("Hash of downloaded package is not valid");
                }

                return(packageInfo);
            }
            catch (Exception)
            {
            }

            return(null);
        }
Beispiel #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!");
                        }
                    }
                }
            }
        }