コード例 #1
0
        public UpdateManager(string urlOrPath,
                             string applicationName        = null,
                             string rootDirectory          = null,
                             IFileDownloader urlDownloader = null)
        {
            Contract.Requires(!String.IsNullOrEmpty(urlOrPath));
            Contract.Requires(!String.IsNullOrEmpty(applicationName));

            updateUrlOrPath      = urlOrPath;
            this.applicationName = applicationName ?? UpdateManager.getApplicationName();
            if (urlDownloader != null)
            {
                this.urlDownloader = urlDownloader;
            }
            else
            {
                this.urlDownloader = (Utility.IsFtpUrl(urlOrPath) ? (IFileDownloader) new FtpFileDownloader() : new FileDownloader());
            }

            if (rootDirectory != null)
            {
                this.rootAppDirectory = Path.Combine(rootDirectory, this.applicationName);
                return;
            }

            this.rootAppDirectory = Path.Combine(rootDirectory ?? GetLocalAppDataDirectory(), this.applicationName);
        }
コード例 #2
0
        public static ReleasePackage GetPreviousRelease(IEnumerable <ReleaseEntry> releaseEntries, IReleasePackage package, string targetDir, string prevReleasePath = null, IFullLogger log = null)
        {
            {
                if (releaseEntries == null || !releaseEntries.Any())
                {
                    return(null);
                }
                var first = releaseEntries
                            .Where(x => x.IsDelta == false).Where(x => x.IsDelta == false)
                            .Where(x => x.Version < package.ToSemanticVersion()).Where(x => x.Version < package.ToSemanticVersion())
                            .OrderByDescending(x => x.Version).OrderByDescending(x => x.Version)
                            .Select(x => new ReleasePackage(Path.Combine(targetDir, x.Filename), true))
                            .FirstOrDefault();

                if (first != null)
                {
                    var prevReleaseFilePath = Path.Combine(targetDir, first.SuggestedReleaseFileName);
                    if (!File.Exists(prevReleaseFilePath) && !string.IsNullOrEmpty(prevReleasePath))
                    {
                        IFileDownloader downloader;
                        if (Utility.IsHttpUrl(prevReleasePath))
                        {
                            downloader = new FileDownloader();
                        }
                        else if (Utility.IsFtpUrl(prevReleasePath))
                        {
                            downloader = new FtpFileDownloader();
                        }
                        else
                        {
                            return(null);
                        }

                        try
                        {
                            downloader.DownloadFile(Path.Combine(prevReleasePath, first.SuggestedReleaseFileName), prevReleaseFilePath, null);
                        }
                        catch (Exception)
                        {
                            return(null);
                        }
                    }

                    if (File.Exists(prevReleaseFilePath))
                    {
                        return(new ReleasePackage(prevReleaseFilePath, true));
                    }
                }

                return(null);
            }
        }
コード例 #3
0
            public async Task DownloadReleases(string updateUrlOrPath, IEnumerable <ReleaseEntry> releasesToDownload, Action <int> progress = null, IFileDownloader urlDownloader = null)
            {
                progress = progress ?? (_ => { });
                if (urlDownloader == null && Utility.IsHttpUrl(updateUrlOrPath))
                {
                    urlDownloader = new FileDownloader();
                }
                else if (urlDownloader == null && Utility.IsFtpUrl(updateUrlOrPath))
                {
                    urlDownloader = new FtpFileDownloader();
                }
                var packagesDirectory = Path.Combine(rootAppDirectory, "packages");

                double current     = 0;
                double toIncrement = 100.0 / releasesToDownload.Count();

                if (Utility.IsHttpUrl(updateUrlOrPath) || Utility.IsFtpUrl(updateUrlOrPath))
                {
                    // From Internet
                    await releasesToDownload.ForEachAsync(async x => {
                        var targetFile   = Path.Combine(packagesDirectory, x.Filename);
                        double component = 0;
                        await downloadRelease(updateUrlOrPath, x, urlDownloader, targetFile, p => {
                            lock (progress) {
                                current  -= component;
                                component = toIncrement / 100.0 * p;
                                progress((int)Math.Round(current += component));
                            }
                        });

                        checksumPackage(x);
                    });
                }
                else
                {
                    // From Disk
                    await releasesToDownload.ForEachAsync(x => {
                        var targetFile = Path.Combine(packagesDirectory, x.Filename);

                        File.Copy(
                            Path.Combine(updateUrlOrPath, x.Filename),
                            targetFile,
                            true);

                        lock (progress) progress((int)Math.Round(current += toIncrement));
                        checksumPackage(x);
                    });
                }
            }
コード例 #4
0
            public async Task <UpdateInfo> CheckForUpdate(
                string localReleaseFile,
                string updateUrlOrPath,
                bool ignoreDeltaUpdates       = false,
                Action <int> progress         = null,
                IFileDownloader urlDownloader = null)
            {
                progress = progress ?? (_ => { });

                var localReleases = Enumerable.Empty <ReleaseEntry>();
                var stagingId     = getOrCreateStagedUserId();

                bool shouldInitialize = false;

                try {
                    localReleases = Utility.LoadLocalReleases(localReleaseFile);
                } catch (Exception ex) {
                    // Something has gone pear-shaped, let's start from scratch
                    this.Log().WarnException("Failed to load local releases, starting from scratch", ex);
                    shouldInitialize = true;
                }

                if (shouldInitialize)
                {
                    await initializeClientAppDirectory();
                }

                string releaseFile;

                var latestLocalRelease = localReleases.Count() > 0 ?
                                         localReleases.MaxBy(x => x.Version).First() :
                                         default(ReleaseEntry);

                // Fetch the remote RELEASES file, whether it's a local dir or an
                // HTTP URL
                if (Utility.IsHttpUrl(updateUrlOrPath) || Utility.IsFtpUrl(updateUrlOrPath))
                {
                    if (updateUrlOrPath.EndsWith("/"))
                    {
                        updateUrlOrPath = updateUrlOrPath.Substring(0, updateUrlOrPath.Length - 1);
                    }

                    this.Log().Info("Downloading RELEASES file from {0}", updateUrlOrPath);

                    int retries = 3;

retry:

                    try {
                        var uri = Utility.AppendPathToUri(new Uri(updateUrlOrPath), "RELEASES");

                        if (latestLocalRelease != null)
                        {
                            uri = Utility.AddQueryParamsToUri(uri, new Dictionary <string, string> {
                                { "id", latestLocalRelease.PackageName },
                                { "localVersion", latestLocalRelease.Version.ToString() },
                                { "arch", Environment.Is64BitOperatingSystem ? "amd64" : "x86" }
                            });
                        }

                        var data = await urlDownloader.DownloadUrl(uri.ToString());

                        releaseFile = Encoding.UTF8.GetString(data);
                    } catch (WebException ex) {
                        this.Log().InfoException("Download resulted in WebException (returning blank release list)", ex);

                        if (retries <= 0)
                        {
                            throw;
                        }
                        retries--;
                        goto retry;
                    }

                    progress(33);
                }
                else
                {
                    this.Log().Info("Reading RELEASES file from {0}", updateUrlOrPath);

                    if (!Directory.Exists(updateUrlOrPath))
                    {
                        var message = String.Format(
                            "The directory {0} does not exist, something is probably broken with your application",
                            updateUrlOrPath);

                        throw new Exception(message);
                    }

                    var fi = new FileInfo(Path.Combine(updateUrlOrPath, "RELEASES"));
                    if (!fi.Exists)
                    {
                        var message = String.Format(
                            "The file {0} does not exist, something is probably broken with your application",
                            fi.FullName);

                        this.Log().Warn(message);

                        var packages = (new DirectoryInfo(updateUrlOrPath)).GetFiles("*.nupkg");
                        if (packages.Length == 0)
                        {
                            throw new Exception(message);
                        }

                        // NB: Create a new RELEASES file since we've got a directory of packages
                        ReleaseEntry.WriteReleaseFile(
                            packages.Select(x => ReleaseEntry.GenerateFromFile(x.FullName)), fi.FullName);
                    }

                    releaseFile = File.ReadAllText(fi.FullName, Encoding.UTF8);
                    progress(33);
                }

                var ret            = default(UpdateInfo);
                var remoteReleases = ReleaseEntry.ParseReleaseFileAndApplyStaging(releaseFile, stagingId);

                progress(66);

                if (!remoteReleases.Any())
                {
                    throw new Exception("Remote release File is empty or corrupted");
                }

                ret = determineUpdateInfo(localReleases, remoteReleases, ignoreDeltaUpdates);

                progress(100);
                return(ret);
            }