Пример #1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="asset"></param>
        /// <param name="destinationDir"></param>
        /// <param name="streams"></param>
        /// <returns></returns>
        private static bool ExtractToDirectory(AssetObject asset, string destinationDir, IReadOnlyDictionary <string, FileStream> streams)
        {
            var dir      = FileUtils.GetZombieDownloadsDirectory();
            var filePath = Path.Combine(dir, asset.Name);

            if (!File.Exists(filePath))
            {
                return(false);
            }

            try
            {
                using (var zip = ZipFile.Open(filePath, ZipArchiveMode.Read))
                {
                    foreach (var file in zip.Entries)
                    {
                        var completeFileName = Path.Combine(FilePathUtils.CreateUserSpecificPath(destinationDir), file.FullName);

                        if (file.Name == string.Empty)
                        {
                            continue;                            // dir entry
                        }
                        // make sure that file is not locked
                        var stream = streams.ContainsKey(completeFileName) ? streams[completeFileName] : null;
                        stream?.Close();

                        if (stream == null)
                        {
                            // we didn't add it to streams which means that directory didn't exist
                            var path = Path.GetDirectoryName(completeFileName);
                            if (!Directory.Exists(path))
                            {
                                Directory.CreateDirectory(path);
                            }
                        }

                        file.ExtractToFile(completeFileName, true);
                    }
                }
            }
            catch (Exception e)
            {
                _logger.Fatal(e.Message);
                return(false);
            }

            return(true);
        }
Пример #2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="settings"></param>
        /// <param name="asset"></param>
        /// <param name="destinationDir"></param>
        /// <param name="streams"></param>
        /// <returns></returns>
        private static bool LockAllContents(ZombieSettings settings, AssetObject asset, string destinationDir, out Dictionary <string, FileStream> streams)
        {
            streams = new Dictionary <string, FileStream>();
            var dir      = FileUtils.GetZombieDownloadsDirectory();
            var filePath = Path.Combine(dir, asset.Name);

            if (!GitHubUtils.DownloadAssets(settings, asset.Url, filePath))
            {
                return(false);
            }

            try
            {
                using (var zip = ZipFile.Open(filePath, ZipArchiveMode.Read))
                {
                    foreach (var file in zip.Entries)
                    {
                        var completeFileName = Path.Combine(FilePathUtils.CreateUserSpecificPath(destinationDir), file.FullName);
                        if (file.Name == string.Empty || !Directory.Exists(Path.GetDirectoryName(completeFileName)))
                        {
                            continue;
                        }

                        var fs = new FileStream(completeFileName, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None);
                        streams.Add(completeFileName, fs);
                    }
                }
            }
            catch (Exception e)
            {
                _logger.Fatal(e.Message);
                return(false);
            }

            return(true);
        }
Пример #3
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="settings"></param>
        public async void GetLatestRelease(ZombieSettings settings)
        {
            if (string.IsNullOrEmpty(settings?.AccessToken) || string.IsNullOrEmpty(settings.Address))
            {
                UpdateUI("Connection failed!", ConnectionResult.Failure);
                return;
            }

            var response = await GetLatestReleaseFromGitHub(settings);

            if (response.StatusCode != HttpStatusCode.OK)
            {
                UpdateUI("Connection failed!", ConnectionResult.Failure);
                return;
            }

            var release        = response.Data;
            var currentVersion = Properties.Settings.Default["CurrentVersion"].ToString();

            if (!release.Assets.Any() || new Version(release.TagName).CompareTo(new Version(currentVersion)) <= 0)
            {
                UpdateUI("Your release is up to date!", ConnectionResult.UpToDate, release);
                return;
            }

            var dir        = FileUtils.GetZombieDownloadsDirectory();
            var downloaded = 0;

            foreach (var asset in release.Assets)
            {
                var filePath = Path.Combine(dir, asset.Name);
                if (GitHubUtils.DownloadAssets(settings, asset.Url, filePath))
                {
                    downloaded++;
                }
            }

            if (downloaded != release.Assets.Count)
            {
                UpdateUI("Failed to download assets!", ConnectionResult.Failure);
                return;
            }

            // (Konrad) Let's get updated settings, they might be local, or remote.
            // We need latest settings since there might be changes to the target locations.
            ZombieSettings newSettings;

            if (File.Exists(settings.SettingsLocation))
            {
                if (!SettingsUtils.TryGetStoredSettings(settings.SettingsLocation, out newSettings))
                {
                    UpdateUI("Could not get latest local Zombie Settings!", ConnectionResult.Failure);
                    return;
                }
            }
            else
            {
                if (!SettingsUtils.TryGetRemoteSettings(settings.SettingsLocation, out newSettings))
                {
                    UpdateUI("Could not get latest remote Zombie Settings!", ConnectionResult.Failure);
                    return;
                }
            }

            // (Konrad) Let's make sure that we own the files that we are trying to override
            var fileStreams = new Dictionary <string, FileStream>();

            foreach (var loc in newSettings.DestinationAssets)
            {
                foreach (var asset in loc.Assets)
                {
                    if (asset.IsArchive())
                    {
                        if (LockAllContents(settings, asset, loc.DirectoryPath, out var zippedStreams))
                        {
                            fileStreams = fileStreams.Concat(zippedStreams).GroupBy(x => x.Key)
                                          .ToDictionary(x => x.Key, x => x.First().Value);
                            continue;
                        }

                        UpdateUI("Could not get access to all ZIP contents!", ConnectionResult.Failure);
                        return;
                    }

                    var to = Path.Combine(FilePathUtils.CreateUserSpecificPath(loc.DirectoryPath), asset.Name);
                    try
                    {
                        var fs = new FileStream(to, FileMode.OpenOrCreate, FileAccess.ReadWrite,
                                                FileShare.None);
                        fileStreams.Add(to, fs);
                    }
                    catch (Exception e)
                    {
                        UpdateUI(e.Message, ConnectionResult.Failure);
                        return;
                    }
                }
            }

            // (Konrad) Move assets to target locations
            foreach (var loc in newSettings.DestinationAssets)
            {
                foreach (var asset in loc.Assets)
                {
                    if (asset.IsArchive())
                    {
                        if (ExtractToDirectory(asset, loc.DirectoryPath, fileStreams))
                        {
                            continue;
                        }

                        UpdateUI("Could not override existing ZIP contents!", ConnectionResult.Failure);
                        return;
                    }

                    var from = Path.Combine(dir, asset.Name);
                    var to   = Path.Combine(FilePathUtils.CreateUserSpecificPath(loc.DirectoryPath), asset.Name);

                    // make sure that file is not locked
                    var stream = fileStreams[to];
                    stream?.Close();

                    if (FileUtils.Copy(@from, @to))
                    {
                        continue;
                    }

                    UpdateUI("Could not override existing file!", ConnectionResult.Failure);
                    return;
                }
            }

            // (Konrad) Remove temporary assets
            if (!FileUtils.DeleteDirectory(dir))
            {
                UpdateUI("Could not remove temporary download assets!", ConnectionResult.Failure);
                return;
            }

            // (Konrad) Update UI and save current version
            Properties.Settings.Default.CurrentVersion = release.TagName;
            Properties.Settings.Default.Save();

            _logger.Info("Successfully updated to version: " + release.TagName);
            Messenger.Default.Send(new UpdateStatus {
                Status = "Successfully updated to version: " + release.TagName
            });
            Messenger.Default.Send(new ReleaseDownloaded
            {
                Release = release,
                Result  = ConnectionResult.Success
            });
        }