Esempio n. 1
0
 public void Rollback()
 {
     if (File.Exists(LogPath))
     {
         var updater = new UpdaterLog(LogPath, false);
         updater.Revert();
     }
 }
Esempio n. 2
0
        public async Task ApplyPatch(VersionModel patchInfo)
        {
            try
            {
                CurrentState = UpdateState.DownloadingPatch;


                OnUpdateProgress(new UpdateProgressModel
                {
                    State          = CurrentState,
                    TotalBytes     = 1,
                    CompletedBytes = 0
                });

                if (!_updateFilesDir.Exists)
                {
                    _updateFilesDir.Create();
                }
                else
                {
                    _updateFilesDir.Delete(true);
                    _updateFilesDir.Create();
                }

                var patchZipFile = new FileInfo(_updateFilesDir + "\\patch.zip");

                var extractedDir = new DirectoryInfo(_updateFilesDir + "\\Patch");

                using (var wc = new WebClient())
                {
                    wc.DownloadProgressChanged += Wc_DownloadProgressChanged;

                    await wc.DownloadFileTaskAsync(_websiteUrl + $"/{patchInfo.Version}.zip", patchZipFile.FullName);
                }

                CurrentState = UpdateState.ApplyingPatch;

                ZipFile.ExtractToDirectory(patchZipFile.FullName, extractedDir.FullName);

                var patch = JsonConvert.DeserializeObject <PatchModel>(File.ReadAllText(extractedDir.FullName + "\\Info.json"));

                var  totalBytes  = patch.NewFiles.Sum(q => q.Size) + patch.UpdatedFiles.Sum(q => q.Size);
                long loadedBytes = 0;
                OnUpdateProgress(new UpdateProgressModel
                {
                    State          = CurrentState,
                    TotalBytes     = totalBytes,
                    CompletedBytes = loadedBytes
                });

                var patchContentDir = new DirectoryInfo(extractedDir.FullName + "\\Data");


                using (var log = new UpdaterLog(LogPath, true))
                {
                    if (patch.UpdatedFiles != null)
                    {
                        foreach (var updatedFileName in patch.UpdatedFiles)
                        {
                            var fi = new FileInfo(_workingDir.FullName + updatedFileName.RelativePath);
                            if (fi.Directory.Exists == false)
                            {
                                fi.Directory.Create();
                            }

                            string realFileName;

                            bool isPatch = false;

                            if (fi.FullName.EndsWith(".patch", StringComparison.InvariantCultureIgnoreCase))
                            {
                                realFileName = fi.FullName.Substring(0, fi.FullName.Length - 6);
                                isPatch      = true;
                            }
                            else
                            {
                                realFileName = fi.FullName;
                            }

                            File.Delete(realFileName + ".bak");
                            File.Move(realFileName, realFileName + ".bak");

                            log.WriteUpdate(realFileName, realFileName + ".bak");

                            if (isPatch)
                            {
                                using (var input = File.OpenRead(realFileName + ".bak"))
                                    using (var output = File.OpenWrite(realFileName))
                                    {
                                        BinaryPatchUtility.Apply(input,
                                                                 () => File.Open(patchContentDir.FullName + updatedFileName.RelativePath, FileMode.Open, FileAccess.Read, FileShare.Read),
                                                                 output);
                                    }


                                File.Delete(patchContentDir.FullName + updatedFileName.RelativePath);
                            }

                            loadedBytes += updatedFileName.Size;

                            OnUpdateProgress(new UpdateProgressModel
                            {
                                State          = CurrentState,
                                TotalBytes     = totalBytes,
                                CompletedBytes = loadedBytes
                            });
                            Thread.Sleep(1);
                        }
                    }

                    if (patch.NewFiles != null)
                    {
                        foreach (var newFileName in patch.NewFiles)
                        {
                            var fi = new FileInfo(_workingDir.FullName + newFileName.RelativePath);
                            if (fi.Directory.Exists == false)
                            {
                                fi.Directory.Create();
                            }

                            log.WriteAdd(fi.FullName);

                            if (fi.Exists)
                            {
                                fi.Delete();
                            }

                            File.Move(patchContentDir.FullName + newFileName.RelativePath, fi.FullName);

                            loadedBytes += newFileName.Size;
                            OnUpdateProgress(new UpdateProgressModel
                            {
                                State          = CurrentState,
                                TotalBytes     = totalBytes,
                                CompletedBytes = loadedBytes
                            });
                            Thread.Sleep(1);
                        }
                    }

                    if (patch.DeletedFiles != null)
                    {
                        foreach (var patchDeletedFile in patch.DeletedFiles)
                        {
                            var fi = new FileInfo(_workingDir + patchDeletedFile);

                            File.Delete(fi.FullName + ".bak");
                            File.Move(fi.FullName, fi.FullName + ".bak");

                            log.WriteDelete(fi.FullName, fi.FullName + ".bak");
                        }
                    }

                    log.Complete();
                }

                _updaterConfig.VersionProvider.SaveVersion(patch.Version);

                CurrentState = UpdateState.Idle;

                _updateFilesDir.Delete(true);

                OnPatchingCompleted(patch);
            }
            catch (Exception e)
            {
                CurrentState = UpdateState.Idle;
                OnPatchingError(e);

                Rollback();
            }
        }