예제 #1
0
        // For self-patching applications only - should be called after Run(true) returns PatchResult.Success
        // Starts specified self patcher executable with required parameters
        public bool ApplySelfPatch(string selfPatcherExecutable, string postSelfPatchExecutable = null)
        {
            IsRunning = true;
            Operation = PatchOperation.ApplyingSelfPatch;

            comms.InitializeFileLogger();
            comms.ListenerCallStarted();

            try
            {
                selfPatcherExecutable = selfPatcherExecutable.Trim();
                if (postSelfPatchExecutable != null)
                {
                    postSelfPatchExecutable = postSelfPatchExecutable.Trim();
                }

                if (!File.Exists(selfPatcherExecutable))
                {
                    Result      = PatchResult.Failed;
                    FailReason  = PatchFailReason.SelfPatcherNotFound;
                    FailDetails = Localization.Get(StringId.E_SelfPatcherDoesNotExist);

                    comms.Log(comms.FailDetails);
                    return(false);
                }

                string instructionsPath          = comms.CachePath + PatchParameters.SELF_PATCH_INSTRUCTIONS_FILENAME;
                string completedInstructionsPath = comms.CachePath + PatchParameters.SELF_PATCH_COMPLETED_INSTRUCTIONS_FILENAME;
                if (!File.Exists(instructionsPath))
                {
                    Result      = PatchResult.Failed;
                    FailReason  = PatchFailReason.Unknown;
                    FailDetails = "";

                    comms.LogToFile(Localization.Get(StringId.E_XDoesNotExist, instructionsPath));
                    return(false);
                }

                FileInfo selfPatcher = new FileInfo(selfPatcherExecutable);

                string args = "\"" + instructionsPath + "\" \"" + completedInstructionsPath + "\"";
                if (!string.IsNullOrEmpty(postSelfPatchExecutable) && File.Exists(postSelfPatchExecutable))
                {
                    args += " \"" + postSelfPatchExecutable + "\"";
                }

                ProcessStartInfo startInfo = new ProcessStartInfo(selfPatcher.FullName)
                {
                    Arguments        = args,
                    WorkingDirectory = selfPatcher.DirectoryName
                };

                Process.Start(startInfo);
                Result = PatchResult.Success;
            }
            catch (Exception e)
            {
                Result      = PatchResult.Failed;
                FailReason  = PatchFailReason.FatalException;
                FailDetails = e.ToString();

                comms.LogToFile(e);
                return(false);
            }
            finally
            {
                comms.DisposeFileLogger();

                IsRunning = false;
                comms.ListenerCallFinished();
            }

            Process.GetCurrentProcess().Kill();
            return(true);
        }
예제 #2
0
        public PatchResult Run()
        {
            if (comms.Cancel)
            {
                return(PatchResult.Failed);
            }

            if (comms.IsUnderMaintenance())
            {
                return(PatchResult.Failed);
            }

            Stopwatch timer = Stopwatch.StartNew();

            comms.Stage = PatchStage.CalculatingFilesToUpdate;

            comms.Log(Localization.Get(StringId.CalculatingNewOrChangedFiles));
            List <VersionItem> filesToUpdate = FindFilesToUpdate();

            if (filesToUpdate.Count == 0)
            {
                return(PatchResult.AlreadyUpToDate);
            }

            if (comms.Cancel)
            {
                return(PatchResult.Failed);
            }

            comms.Log(Localization.Get(StringId.CalculatingFilesToDownload));
            List <VersionItem> filesToDownload = FindFilesToDownload(filesToUpdate);

            if (comms.Cancel)
            {
                return(PatchResult.Failed);
            }

            if (filesToDownload.Count > 0 && comms.VerifyFiles)
            {
                comms.Stage = PatchStage.VerifyingFilesOnServer;

                for (int i = 0; i < filesToDownload.Count; i++)
                {
                    if (comms.Cancel)
                    {
                        return(PatchResult.Failed);
                    }

                    VersionItem item = filesToDownload[i];
                    long        fileSize;
                    if (!comms.DownloadManager.FileExistsAtUrl(comms.VersionInfo.GetDownloadURLFor(item), out fileSize))
                    {
                        comms.FailReason  = PatchFailReason.FileDoesNotExistOnServer;
                        comms.FailDetails = Localization.Get(StringId.E_FileXDoesNotExistOnServer, item.Path);

                        return(PatchResult.Failed);
                    }
                    else if (fileSize > 0L && fileSize != item.CompressedFileSize)
                    {
                        comms.FailReason  = PatchFailReason.FileIsNotValidOnServer;
                        comms.FailDetails = Localization.Get(StringId.E_FileXIsNotValidOnServer, item.Path);

                        return(PatchResult.Failed);
                    }
                }
            }

            if (filesToDownload.Count > 0)
            {
                comms.Log(Localization.Get(StringId.DownloadingXFiles, filesToDownload.Count));
            }

            if (filesToUpdate.Count > 0)
            {
                comms.Log(Localization.Get(StringId.UpdatingXFiles, filesToUpdate.Count));
            }

            Stopwatch downloadTimer = Stopwatch.StartNew();

            if (!DownloadAndUpdateFiles(filesToDownload, filesToUpdate))
            {
                return(PatchResult.Failed);
            }

            comms.Log(Localization.Get(StringId.AllFilesAreDownloadedInXSeconds, downloadTimer.ElapsedSeconds()));

            PatchUtils.DeleteDirectory(comms.DownloadsPath);

            comms.Log(Localization.Get(StringId.PatchAppliedInXSeconds, timer.ElapsedSeconds()));

            return(PatchResult.Success);
        }
예제 #3
0
        // For self-patching applications only - should be called after Run(true) returns PatchResult.Success
        // Starts specified self patcher executable with required parameters
        public bool ApplySelfPatch(string selfPatcherExecutable, string postSelfPatchExecutable = null)
        {
            selfPatcherExecutable = selfPatcherExecutable.Trim();
            if (postSelfPatchExecutable != null)
            {
                postSelfPatchExecutable = postSelfPatchExecutable.Trim();
            }

            if (!File.Exists(selfPatcherExecutable))
            {
                comms.Log(Localization.Get(StringId.E_SelfPatcherDoesNotExist));
                return(false);
            }

            string instructionsPath          = comms.CachePath + PatchParameters.SELF_PATCH_INSTRUCTIONS_FILENAME;
            string completedInstructionsPath = comms.CachePath + PatchParameters.SELF_PATCH_COMPLETED_INSTRUCTIONS_FILENAME;

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

            FileInfo selfPatcher = new FileInfo(selfPatcherExecutable);

            string args = "\"" + instructionsPath + "\" \"" + completedInstructionsPath + "\"";

            if (!string.IsNullOrEmpty(postSelfPatchExecutable) && File.Exists(postSelfPatchExecutable))
            {
                args += " \"" + postSelfPatchExecutable + "\"";
            }

            ProcessStartInfo startInfo = new ProcessStartInfo(selfPatcher.FullName)
            {
                Arguments        = args,
                WorkingDirectory = selfPatcher.DirectoryName
            };

            Process.Start(startInfo);
            Process.GetCurrentProcess().Kill();

            return(true);
        }
        public PatchResult Run()
        {
            if (comms.Cancel)
            {
                return(PatchResult.Failed);
            }

            if (comms.IsUnderMaintenance())
            {
                return(PatchResult.Failed);
            }

            if (patchInfo.Files.Count > 0)
            {
                PatchUtils.DeleteDirectory(patchDecompressPath);
                Directory.CreateDirectory(patchDecompressPath);
            }

            if (comms.Cancel)
            {
                return(PatchResult.Failed);
            }

            Stopwatch timer = Stopwatch.StartNew();

            if (patchInfo.Files.Count > 0)
            {
                FileInfo patchFile = new FileInfo(patchDownloadPath);
                if (!patchFile.Exists || !patchFile.MatchesSignature(patchInfo.CompressedFileSize, patchInfo.CompressedMd5Hash))
                {
                    comms.Stage = PatchStage.DownloadingFiles;

                    Stopwatch downloadTimer = Stopwatch.StartNew();
                    comms.Log(Localization.Get(StringId.DownloadingPatchX, patchInfo.PatchVersion()));

                    patchFile = comms.DownloadManager.DownloadFileFromURLToPath(patchInfo.DownloadURL, patchDownloadPath, patchInfo.CompressedFileSize);
                    if (patchFile == null)
                    {
                        comms.FailReason  = PatchFailReason.DownloadError;
                        comms.FailDetails = Localization.Get(StringId.E_PatchXCouldNotBeDownloaded, patchInfo.PatchVersion());

                        return(PatchResult.Failed);
                    }
                    else if (!patchFile.MatchesSignature(patchInfo.CompressedFileSize, patchInfo.CompressedMd5Hash))
                    {
                        comms.FailReason  = PatchFailReason.CorruptDownloadError;
                        comms.FailDetails = Localization.Get(StringId.E_DownloadedFileXIsCorrupt, patchInfo.PatchVersion());

                        return(PatchResult.Failed);
                    }
                    else
                    {
                        comms.Log(Localization.Get(StringId.XDownloadedInYSeconds, patchInfo.PatchVersion(), downloadTimer.ElapsedSeconds()));
                    }
                }

                if (comms.Cancel)
                {
                    return(PatchResult.Failed);
                }

                comms.Stage = PatchStage.ExtractingFilesFromArchive;
                comms.Log(Localization.Get(StringId.DecompressingPatchX, patchInfo.PatchVersion()));

                ZipUtils.DecompressFolderLZMA(patchFile.FullName, patchDecompressPath);

                comms.Stage = PatchStage.UpdatingFiles;
                comms.Log(Localization.Get(StringId.UpdatingXFiles, patchInfo.Files.Count));

                int failedItemCount = 0;
                for (int i = 0; i < patchInfo.Files.Count; i++)
                {
                    if (comms.Cancel)
                    {
                        return(PatchResult.Failed);
                    }

                    string fileRelativePath     = patchInfo.Files[i].Path;
                    string diffFileAbsolutePath = patchDecompressPath + fileRelativePath;
                    if (!File.Exists(diffFileAbsolutePath))
                    {
                        comms.Log(Localization.Get(StringId.E_DiffOfXDoesNotExist, Path.GetFileName(fileRelativePath)));

                        failedItemCount++;
                        continue;
                    }

                    string decompressAbsolutePath = comms.DecompressedFilesPath + fileRelativePath;
                    if (comms.SelfPatching && ApplyDiffToFile(decompressAbsolutePath, diffFileAbsolutePath, decompressAbsolutePath, i))
                    {
                        continue;
                    }

                    string localFileAbsolutePath = comms.RootPath + fileRelativePath;
                    string targetPath            = comms.SelfPatching ? decompressAbsolutePath : localFileAbsolutePath;
                    if (!ApplyDiffToFile(localFileAbsolutePath, diffFileAbsolutePath, targetPath, i))
                    {
                        failedItemCount++;
                    }
                }

                comms.Log(Localization.Get(StringId.XFilesUpdatedSuccessfully, patchInfo.Files.Count - failedItemCount, patchInfo.Files.Count));
            }

            if (patchInfo.RenamedFiles.Count > 0)
            {
                comms.Log(Localization.Get(StringId.RenamingXFiles, patchInfo.RenamedFiles.Count));
                if (!RenameItems(patchInfo.RenamedFiles))
                {
                    return(PatchResult.Failed);
                }
            }

            // Updating version code to the latest one will be done by SimplePatchTool, after checking
            // whether or not all files are correctly updated
            if (patchInfo.ToVersion < comms.VersionInfo.Version)
            {
                comms.UpdateVersion(patchInfo.ToVersion);
            }

            if (patchInfo.Files.Count > 0)
            {
                PatchUtils.DeleteDirectory(patchDecompressPath);
                File.Delete(patchDownloadPath);
            }

            comms.Log(Localization.Get(StringId.PatchAppliedInXSeconds, timer.ElapsedSeconds()));
            return(PatchResult.Success);
        }