示例#1
0
        /// <summary>
        /// Check cache from update and synchronize files from patches
        /// </summary>
        private void LoadCache()
        {
            var patchCachePath = Path.GetFileNameWithoutExtension(System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName) + ".patch.cache";

            if (File.Exists(patchCachePath))
            {
                Version cacheVersion = null;
                Dictionary <string, PatchFile> cachePatch = null;
                // Read patch file structure
                using (var reader = new BinaryReader(new FileStream(patchCachePath, FileMode.Open)))
                {
                    cacheVersion = new Version(reader.ReadString());
                    // for each patch file
                    var filesCount = reader.ReadInt32();
                    cachePatch = new Dictionary <string, PatchFile>(filesCount);
                    for (int j = 0; j < filesCount; j++)
                    {
                        var file = new PatchFile(reader.ReadString(), reader.ReadString(), reader.ReadString());
                        cachePatch.Add(file.FullPath, file);
                    }
                }
                // Merge current patches with cache patch to avoid download all the patch again
                foreach (var version in Patches.Keys)
                {
                    if (version == cacheVersion)
                    {
                        var patch = Patches[version];
                        // Create a keys copy to remove from dictionary without issues
                        var paths = new List <string>(patch.Keys);
                        // If file doesn't exist on cache patch, then is already updated
                        foreach (var path in paths)
                        {
                            // Avoid update it again
                            if (!cachePatch.ContainsKey(path))
                            {
                                patch.Remove(path);
                                PatchFiles.Remove(path);
                            }
                        }
                        // Indicate update has been paused
                        IsUpdatePaused = true;
                    }
                }
            }
        }
示例#2
0
        /// <summary>
        /// Start/continue updating the application
        /// </summary>
        private async Task StartUpdating()
        {
            IsUpdatePaused = false;

            // Check there is files to update
            if (PatchFiles == null || PatchFiles.Count == 0)
            {
                return;
            }

            // Path to check if the executable needs to be updated
            var exePath = Path.GetFileName(System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName);

            // Start Downloading files from old patches to new ones
            var versions = new List <Version>(Patches.Keys);

            versions.Sort((a, b) => { return(a.CompareTo(b)); });
            foreach (var version in versions)
            {
                var patch = Patches[version];
                // Create a different instance of keys to remove it without issues
                var paths = new List <string>(patch.Keys);
                // Download and update each file from this version
                for (int i = 0; i < paths.Count; i++)
                {
                    // track updating file
                    var f = m_CurrentFileUpdating = patch[paths[i]];
                    // Check if the file is going to replace this executable
                    bool isExecutable = f.FullPath == exePath;
                    if (isExecutable)
                    {
                        // Check if is not last file to update
                        if (i < (paths.Count - 1))
                        {
                            // Add it again as last one
                            paths.Add(f.FullPath);
                            continue;
                        }
                    }

                    // call event
                    OnFileDownloadReady(f);

                    // track event
                    f.DownloadProgressChanged += OnFileDownloadProgressChanged;

                    // download it
                    await f.StartDownload();

                    // untrack event
                    f.DownloadProgressChanged -= OnFileDownloadProgressChanged;

                    // Check if download has been paused
                    if (f.IsPaused)
                    {
                        break;
                    }

                    // call event
                    var completedEventArgs = OnFileDownloadCompleted(f);

                    // Check if the updating process is going to be handled by manager
                    if (completedEventArgs.CancelUpdate)
                    {
                        await completedEventArgs.ExecuteAction();
                    }
                    else
                    {
                        // Check if is executable
                        if (isExecutable)
                        {
                            // update it slightly different (delete super old, move old and forget then move new)
                            var thrashPath = Path.Combine(DownloadingPath, exePath + ".old");
                            await Task.Run(() =>
                            {
                                if (File.Exists(thrashPath))
                                {
                                    File.Delete(thrashPath);
                                }
                                File.Move(exePath, thrashPath);
                                File.Move(f.DownloadPath, exePath);
                            });
                        }
                        else
                        {
                            // update it
                            await f.Update();
                        }
                    }

                    // Check if is the executable being updated
                    if (isExecutable)
                    {
                        // delete cache
                        DeleteCache();
                    }
                    else
                    {
                        // Create backup to continue the update on restart
                        SaveCache(version, patch);
                    }

                    // remove it from tracking
                    patch.Remove(f.FullPath);
                    PatchFiles.Remove(f.FullPath);

                    // call event
                    OnFileUpdateCompleted(f);

                    // Start calling a events to restart the application
                    if (isExecutable)
                    {
                        // call event
                        OnPatchCompleted(version);

                        // Check if this is the last file from everything for update
                        if (PatchFiles.Count == 0)
                        {
                            // call event
                            OnUpdateCompleted();
                        }

                        // Restart application
                        OnApplicationRestart();

                        // Execute new executable and exit from this one
                        System.Diagnostics.Process.Start(exePath);
                        Environment.Exit(0);
                    }
                }

                // Stop tracking as updating
                m_CurrentFileUpdating = null;

                // Check if update has been paused
                if (IsUpdatePaused)
                {
                    break;
                }

                // call event
                OnPatchCompleted(version);
            }

            // Patch finished
            if (PatchFiles.Count == 0)
            {
                // delete cache
                DeleteCache();
                // call event
                OnUpdateCompleted();
            }
        }