示例#1
0
        /// <exception cref = "FileNotFoundException">Version info does not exist at path</exception>
        /// <exception cref = "ArgumentException">versionInfoPath is empty</exception>
        /// <exception cref = "UnauthorizedAccessException">Admin priviledges needed to update the version info</exception>
        /// <exception cref = "InvalidOperationException">Version info could not be deserialized</exception>
        public PatchUpdater(string versionInfoPath, LogEvent logger = null)
        {
            versionInfoPath = versionInfoPath.Trim();
            if (string.IsNullOrEmpty(versionInfoPath))
            {
                throw new ArgumentException(Localization.Get(StringId.E_XCanNotBeEmpty, "'versionInfoPath'"));
            }

            if (!File.Exists(versionInfoPath))
            {
                throw new FileNotFoundException(Localization.Get(StringId.E_PatchInfoDoesNotExistAtX, versionInfoPath));
            }

            if (!PatchUtils.CheckWriteAccessToFolder(Path.GetDirectoryName(versionInfoPath)))
            {
                throw new UnauthorizedAccessException(Localization.Get(StringId.E_AccessToXIsForbiddenRunInAdminMode, versionInfoPath));
            }

            this.versionInfoPath = versionInfoPath;
            VersionInfo          = PatchUtils.GetVersionInfoFromPath(versionInfoPath);
            if (VersionInfo == null)
            {
                throw new InvalidOperationException(Localization.Get(StringId.E_VersionInfoCouldNotBeDeserializedFromX, versionInfoPath));
            }

            Logger = logger;
        }
示例#2
0
        /// <exception cref = "DirectoryNotFoundException">Previous patch files' directory does not exist</exception>
        /// <exception cref = "FileNotFoundException">VersionInfo of the previous patch files does not exist</exception>
        /// <exception cref = "FormatException">VersionInfo of the previous patch could not be deserialized</exception>
        public PatchCreator SetPreviousPatchFilesRoot(string previousPatchFilesRoot, bool dontCreatePatchFilesForUnchangedFiles = false)
        {
            if (previousPatchFilesRoot != null)
            {
                previousPatchFilesRoot = previousPatchFilesRoot.Trim();
            }

            if (string.IsNullOrEmpty(previousPatchFilesRoot))
            {
                this.previousPatchFilesRoot = null;
                this.previousVersionInfo    = null;
                this.dontCreatePatchFilesForUnchangedFiles = false;
            }
            else
            {
                previousPatchFilesRoot = PatchUtils.GetPathWithTrailingSeparatorChar(previousPatchFilesRoot);

                if (!Directory.Exists(previousPatchFilesRoot))
                {
                    throw new DirectoryNotFoundException(Localization.Get(StringId.E_XDoesNotExist, previousPatchFilesRoot));
                }

                string previousVersionInfoPath = previousPatchFilesRoot + PatchParameters.VERSION_INFO_FILENAME;
                if (!File.Exists(previousVersionInfoPath))
                {
                    throw new FileNotFoundException(Localization.Get(StringId.E_XDoesNotExist, previousVersionInfoPath));
                }

                VersionInfo previousVersionInfo = PatchUtils.GetVersionInfoFromPath(previousVersionInfoPath);
                if (previousVersionInfo == null)
                {
                    throw new FormatException(Localization.Get(StringId.E_VersionInfoCouldNotBeDeserializedFromX, previousVersionInfoPath));
                }

                this.previousPatchFilesRoot = previousPatchFilesRoot;
                this.previousVersionInfo    = previousVersionInfo;
                this.dontCreatePatchFilesForUnchangedFiles = dontCreatePatchFilesForUnchangedFiles;
            }

            return(this);
        }
        private PatchResult GeneratePatchInternal()
        {
            if (!Directory.Exists(versionsPath))
            {
                Log(Localization.Get(StringId.E_XDoesNotExist, versionsPath));
                return(PatchResult.Failed);
            }

            if (!File.Exists(projectInfoPath))
            {
                Log(Localization.Get(StringId.E_XDoesNotExist, projectInfoPath));
                return(PatchResult.Failed);
            }

            string[] versions = Directory.GetDirectories(versionsPath);
            if (versions.Length == 0)
            {
                Log(Localization.Get(StringId.E_DirectoryXIsEmpty, versionsPath));
                return(PatchResult.Failed);
            }

            string validationResult = ValidateProject();

            if (!string.IsNullOrEmpty(validationResult))
            {
                Log(validationResult);
                return(PatchResult.Failed);
            }

            Stopwatch timer = Stopwatch.StartNew();

            // Here's how it works:
            // Move previous incremental patch files to Temp\IncrementalFormer
            // Generate repair patch and installer patch files on Temp\Output
            // Foreach incremental patch to generate:
            //   Generate incremental patch files on Temp\Incremental
            //   Move the incremental patch files from there to Temp\IncrementalFormer
            // Replace the contents of outputPath with Temp\Output:
            //   Delete outputPath directory
            //   Move Temp\Output to outputPath
            //   Move Temp\IncrementalFormer to outputPath
            // Delete Temp
            string tempRoot                   = projectRoot + "Temp" + Path.DirectorySeparatorChar;
            string tempOutput                 = tempRoot + "Output" + Path.DirectorySeparatorChar;
            string tempIncrementalOutput      = tempRoot + "Incremental" + Path.DirectorySeparatorChar;
            string tempPrevIncrementalPatches = tempRoot + "IncrementalFormer" + Path.DirectorySeparatorChar;

            PatchUtils.DeleteDirectory(tempOutput);
            PatchUtils.DeleteDirectory(tempIncrementalOutput);

            // Preserve the previous incremental patches
            string versionInfoPath        = outputPath + PatchParameters.VERSION_INFO_FILENAME;
            string incrementalPatchesPath = outputPath + PatchParameters.INCREMENTAL_PATCH_DIRECTORY;

            if (Directory.Exists(incrementalPatchesPath))
            {
                PatchUtils.MoveDirectory(incrementalPatchesPath, tempPrevIncrementalPatches);
            }

            List <IncrementalPatch> incrementalPatches = new List <IncrementalPatch>();

            if (File.Exists(versionInfoPath))
            {
                VersionInfo oldVersionInfo = PatchUtils.GetVersionInfoFromPath(versionInfoPath);
                if (oldVersionInfo != null)
                {
                    incrementalPatches.AddRange(oldVersionInfo.IncrementalPatches);
                }
            }

            Array.Sort(versions, new VersionComparer());

            string      latestVersion = versions[versions.Length - 1];
            ProjectInfo projectInfo   = PatchUtils.GetProjectInfoFromPath(projectInfoPath);

            if (projectInfo.IsSelfPatchingApp && Directory.Exists(selfPatcherPath) && Directory.GetFileSystemEntries(selfPatcherPath).Length > 0)
            {
                PatchUtils.CopyDirectory(selfPatcherPath, Path.Combine(latestVersion, PatchParameters.SELF_PATCHER_DIRECTORY));
            }

            patchCreator = new PatchCreator(latestVersion, tempOutput, projectInfo.Name, Path.GetFileName(latestVersion)).SetListener(this).
                           SetCompressionFormat(projectInfo.CompressionFormatRepairPatch, projectInfo.CompressionFormatInstallerPatch, projectInfo.CompressionFormatIncrementalPatch).
                           CreateRepairPatch(projectInfo.CreateRepairPatch).CreateInstallerPatch(projectInfo.CreateInstallerPatch).CreateIncrementalPatch(false).
                           AddIgnoredPaths(projectInfo.IgnoredPaths).SilentMode(silentMode).SetBaseDownloadURL(projectInfo.BaseDownloadURL).SetMaintenanceCheckURL(projectInfo.MaintenanceCheckURL);

            // Generate repair patch and installer patch files
            if (cancel || !ExecuteCurrentPatch())
            {
                return(PatchResult.Failed);
            }

            if (projectInfo.CreateIncrementalPatch && versions.Length > 1)
            {
                string incrementalPatchesGenerated = tempIncrementalOutput + PatchParameters.INCREMENTAL_PATCH_DIRECTORY;
                string versionInfoGenerated        = tempIncrementalOutput + PatchParameters.VERSION_INFO_FILENAME;

                patchCreator = new PatchCreator(latestVersion, tempIncrementalOutput, projectInfo.Name, Path.GetFileName(latestVersion)).SetListener(this).
                               SetCompressionFormat(projectInfo.CompressionFormatRepairPatch, projectInfo.CompressionFormatInstallerPatch, projectInfo.CompressionFormatIncrementalPatch).
                               AddIgnoredPaths(projectInfo.IgnoredPaths).SilentMode(silentMode).CreateRepairPatch(false).CreateInstallerPatch(false);

                for (int i = versions.Length - 2; i >= 0; i--)
                {
                    Log(Localization.Get(StringId.CreatingIncrementalPatchX, Path.GetFileName(versions[i]) + "->" + Path.GetFileName(latestVersion)));

                    // Generate incremental patch files
                    patchCreator.CreateIncrementalPatch(true, versions[i], projectInfo.BinaryDiffQuality);
                    if (cancel || !ExecuteCurrentPatch())
                    {
                        return(PatchResult.Failed);
                    }

                    List <IncrementalPatch> newIncrementalPatches = PatchUtils.GetVersionInfoFromPath(versionInfoGenerated).IncrementalPatches;
                    for (int j = incrementalPatches.Count - 1; j >= 0; j--)
                    {
                        // Don't allow duplicate IncrementalPatch entries
                        for (int k = newIncrementalPatches.Count - 1; k >= 0; k--)
                        {
                            if (incrementalPatches[j].FromVersion == newIncrementalPatches[k].FromVersion && incrementalPatches[j].ToVersion == newIncrementalPatches[k].ToVersion)
                            {
                                incrementalPatches.RemoveAt(j);
                                break;
                            }
                        }
                    }

                    incrementalPatches.AddRange(newIncrementalPatches);

                    // Move incremental patch files to Temp
                    PatchUtils.MoveDirectory(incrementalPatchesGenerated, tempPrevIncrementalPatches);
                    PatchUtils.DeleteDirectory(tempIncrementalOutput);

                    if (!projectInfo.CreateAllIncrementalPatches)
                    {
                        break;
                    }
                }
            }

            PatchUtils.DeleteDirectory(outputPath);
            PatchUtils.MoveDirectory(tempOutput, outputPath);

            if (Directory.Exists(tempPrevIncrementalPatches))
            {
                PatchUtils.MoveDirectory(tempPrevIncrementalPatches, incrementalPatchesPath);
            }

            VersionInfo versionInfo = PatchUtils.GetVersionInfoFromPath(versionInfoPath);

            incrementalPatches.Sort(PatchUtils.IncrementalPatchComparison);
            versionInfo.IncrementalPatches = incrementalPatches;
            PatchUtils.SerializeVersionInfoToXML(versionInfo, versionInfoPath);

            PatchUtils.DeleteDirectory(tempRoot);

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