private XrmSolutionInfo GetXrmSolutionInfoFromStream(StreamReader reader) { XrmSolutionInfo info = null; try { string uniqueName; string version; XElement solutionNode = XElement.Load(reader); uniqueName = solutionNode.Descendants("UniqueName").First().Value; version = solutionNode.Descendants("Version").First().Value; info = new XrmSolutionInfo { UniqueName = uniqueName, Version = version }; } catch (Exception ex) { Logger.LogError(ex.Message); } return(info); }
private bool SkipImport( XrmSolutionInfo info, bool holdingSolution, bool overrideSameVersion) { using (var context = new CIContext(OrganizationService)) { ColumnSet columns = new ColumnSet("version"); if (!holdingSolution) { var baseSolution = GetSolution(info.UniqueName, columns); if (baseSolution == null) { Logger.LogInformation("{0} not currently installed.", info.UniqueName); } else { Logger.LogInformation("{0} currently installed with version: {1}", info.UniqueName, info.Version); } if (baseSolution == null || overrideSameVersion || (info.Version != baseSolution.Version)) { return(false); } else { return(true); } } else { string upgradeName = $"{info.UniqueName}_Upgrade"; var upgradeSolution = GetSolution(upgradeName, columns); if (upgradeSolution == null) { Logger.LogInformation("{0} not currently installed.", upgradeName); } else { Logger.LogInformation("{0} currently installed with version: {1}", upgradeName, info.Version); } if (upgradeSolution == null) { return(false); } else { return(true); } } } }
public bool ExtractSolution( string solutionPackager, string solutionFile, string folder, SolutionPackager_PackageType packageType, string mappingFile, string sourceLoc, bool localize, bool treatWarningsAsErrors, string logsDirectory ) { Logger.LogVerbose("Unpacking Solution: {0}", solutionFile); SolutionXml solutionXml = new SolutionXml(Logger); XrmSolutionInfo info = solutionXml.GetSolutionInfoFromZip(solutionFile); if (info == null) { throw new Exception("Invalid solution file"); } Logger.LogInformation("Unpacking Solution Name: {0} - Version {1}", info.UniqueName, info.Version); SolutionNameGenerator generator = new SolutionNameGenerator(); string zipFile = new FileInfo(solutionFile).Name; string log = string.Empty; if (!string.IsNullOrEmpty(logsDirectory)) { log = $"{logsDirectory}\\PackagerLog_{zipFile.Replace(".zip", "")}_{DateTime.Now.ToString("yyyy_MM_dd__HH_mm")}.txt"; } Logger.LogVerbose("log: {0}", log); SolutionPackager packager = new SolutionPackager( Logger, solutionPackager, solutionFile, folder, log ); bool result = packager.Extract( packageType, mappingFile, true, true, false, sourceLoc, localize, treatWarningsAsErrors); return(result); }
private bool SkipImport( XrmSolutionInfo info, bool holdingSolution, bool overrideSameVersion) { bool skip = false; ColumnSet columns = new ColumnSet("version"); var baseSolution = GetSolution(info.UniqueName, columns); if (baseSolution == null) { Logger.LogInformation("{0} not currently installed.", info.UniqueName); } else { Logger.LogInformation("{0} currently installed with version: {1}", info.UniqueName, info.Version); } if (baseSolution == null || overrideSameVersion || (info.Version != baseSolution.Version)) { skip = false; } else { return(true); } if (holdingSolution) { string upgradeName = $"{info.UniqueName}_Upgrade"; var upgradeSolution = GetSolution(upgradeName, columns); if (upgradeSolution == null) { Logger.LogInformation("{0} not currently installed.", upgradeName); skip = false; } else { Logger.LogInformation("{0} currently installed with version: {1}", upgradeName, info.Version); skip = true; } } return(skip); }
public MissingComponent[] GetMissingComponentsOnTarget( string solutionFilePath) { Logger.LogInformation("Retrieving Missing Components for Solution: {0}", solutionFilePath); if (!File.Exists(solutionFilePath)) { Logger.LogError("Solution File does not exist: {0}", solutionFilePath); throw new FileNotFoundException("Solution File does not exist", solutionFilePath); } SolutionXml solutionXml = new SolutionXml(Logger); XrmSolutionInfo info = solutionXml.GetSolutionInfoFromZip(solutionFilePath); if (info == null) { throw new Exception("Invalid Solution File"); } else { Logger.LogInformation("Solution Unique Name: {0}, Version: {1}", info.UniqueName, info.Version); } byte[] solutionBytes = File.ReadAllBytes(solutionFilePath); var request = new RetrieveMissingComponentsRequest() { CustomizationFile = solutionBytes }; RetrieveMissingComponentsResponse response = OrganizationService.Execute(request) as RetrieveMissingComponentsResponse; Logger.LogInformation("{0} Missing Components retrieved for Solution", response.MissingComponents.Length); return(response.MissingComponents); }
public XrmSolutionInfo GetSolutionInfo(string solutionFilePath) { Logger.LogVerbose("Reading Solution Zip: {0}", solutionFilePath); XrmSolutionInfo info = null; try { string uniqueName; string version; using (ZipArchive solutionZip = ZipFile.Open(solutionFilePath, ZipArchiveMode.Read)) { ZipArchiveEntry solutionEntry = solutionZip.GetEntry("solution.xml"); using (var reader = new StreamReader(solutionEntry.Open())) { XElement solutionNode = XElement.Load(reader); uniqueName = solutionNode.Descendants("UniqueName").First().Value; version = solutionNode.Descendants("Version").First().Value; } } info = new XrmSolutionInfo { UniqueName = uniqueName, Version = version }; } catch (Exception ex) { Logger.LogError(ex.Message); } return(info); }
public SolutionImportResult ImportSolution( string solutionFilePath, bool publishWorkflows, bool convertToManaged, bool overwriteUnmanagedCustomizations, bool skipProductUpdateDependencies, bool holdingSolution, bool overrideSameVersion, bool importAsync, int sleepInterval, int asyncWaitTimeout, Guid?importJobId, bool downloadFormattedLog, string logDirectory, string logFileName ) { Logger.LogInformation("Importing Solution: {0}", solutionFilePath); if (!importJobId.HasValue || importJobId.Value == Guid.Empty) { importJobId = Guid.NewGuid(); } Logger.LogVerbose("ImportJobId {0}", importJobId); if (asyncWaitTimeout == 0) { asyncWaitTimeout = 15 * 60; } Logger.LogVerbose("AsyncWaitTimeout: {0}", asyncWaitTimeout); if (sleepInterval == 0) { sleepInterval = 15; } Logger.LogVerbose("SleepInterval: {0}", sleepInterval); if (!File.Exists(solutionFilePath)) { Logger.LogError("Solution File does not exist: {0}", solutionFilePath); throw new FileNotFoundException("Solution File does not exist", solutionFilePath); } SolutionImportResult result = null; XrmSolutionInfo info = GetSolutionInfo(solutionFilePath); if (info == null) { result = new SolutionImportResult() { ErrorMessage = "Invalid Solution File" }; return(result); } else { Logger.LogInformation("Solution Unique Name: {0}, Version: {1}", info.UniqueName, info.Version); } bool skipImport = SkipImport(info, holdingSolution, overrideSameVersion); if (skipImport) { Logger.LogInformation("Solution Import Skipped"); result = new SolutionImportResult() { Success = true, ImportSkipped = true }; return(result); } if (downloadFormattedLog) { if (string.IsNullOrEmpty(logFileName)) { logFileName = $"{info.UniqueName}_{(info.Version).Replace('.', '_')}_{DateTime.Now.ToString("yyyy_MM_dd__HH_mm")}.xml"; Logger.LogVerbose("Settings logFileName to {0}", logFileName); } if (string.IsNullOrEmpty(logDirectory)) { logDirectory = Path.GetDirectoryName(solutionFilePath); Logger.LogVerbose("Settings logDirectory to {0}", logDirectory); } if (!Directory.Exists(logDirectory)) { Logger.LogError("logDirectory not exist: {0}", logDirectory); throw new DirectoryNotFoundException("logDirectory does not exist"); } } byte[] solutionBytes = File.ReadAllBytes(solutionFilePath); var importSolutionRequest = new ImportSolutionRequest { CustomizationFile = solutionBytes, PublishWorkflows = publishWorkflows, ConvertToManaged = convertToManaged, OverwriteUnmanagedCustomizations = overwriteUnmanagedCustomizations, SkipProductUpdateDependencies = skipProductUpdateDependencies, ImportJobId = importJobId.Value, RequestId = importJobId, HoldingSolution = holdingSolution }; if (importAsync) { Logger.LogVerbose(string.Format("Importing solution in Async Mode")); var asyncRequest = new ExecuteAsyncRequest { Request = importSolutionRequest }; var asyncResponse = OrganizationService.Execute(asyncRequest) as ExecuteAsyncResponse; Guid asyncJobId = asyncResponse.AsyncJobId; Logger.LogVerbose("Awaiting for Async Operation Completion"); AsyncUpdateHandler updateHandler = new AsyncUpdateHandler( Logger, PollingOrganizationService, importJobId.Value); AsyncOperationManager operationManager = new AsyncOperationManager(Logger, PollingOrganizationService); AsyncOperation asyncOperation = operationManager.AwaitCompletion( asyncJobId, asyncWaitTimeout, sleepInterval, updateHandler); Logger.LogInformation("Async Operation completed with status: {0}", ((AsyncOperation_StatusCode)asyncOperation.StatusCode.Value).ToString()); Logger.LogInformation("Async Operation completed with message: {0}", asyncOperation.Message); result = VerifySolutionImport(importAsync, importJobId.Value, asyncOperation, null); } else { Logger.LogVerbose("Importing solution in Sync Mode"); SyncImportHandler importHandler = new SyncImportHandler( Logger, OrganizationService, importSolutionRequest); ImportJobHandler jobHandler = new ImportJobHandler( Logger, OrganizationService, importHandler); Logger.LogVerbose("Creating Import Task"); Action importAction = () => importHandler.ImportSolution(); Task importTask = new Task(importAction); Logger.LogVerbose("Starting Import Task"); importTask.Start(); Logger.LogVerbose("Thread Started. Starting to Query Import Status"); ImportJobManager jobManager = new ImportJobManager(Logger, PollingOrganizationService); jobManager.AwaitImportJob(importJobId.Value, asyncWaitTimeout, sleepInterval, true, jobHandler); importTask.Wait(); result = VerifySolutionImport(importAsync, importJobId.Value, null, importHandler.Error); } if (result.ImportJobAvailable && downloadFormattedLog) { ImportJobManager jobManager = new ImportJobManager(Logger, OrganizationService); jobManager.SaveFormattedLog(importJobId.Value, logDirectory, logFileName); } if (result.Success) { Logger.LogInformation("Solution Import Completed Successfully"); } else { Logger.LogInformation("Solution Import Failed"); } return(result); }
public bool PackSolution( string solutionPackager, string outputFolder, string folder, SolutionPackager_PackageType packageType, bool includeVersionInName, string mappingFile, bool treatWarningsAsErrors, bool incrementReleaseVersion, string version, string logsDirectory ) { Logger.LogVerbose("Packing Solution from: {0}", folder); SolutionXml solutionXml = new SolutionXml(Logger); XrmSolutionInfo info = solutionXml.GetXrmSolutionInfoFromFolder(folder); if (info == null) { throw new Exception("Invalid solution file"); } Logger.LogInformation("Packing Solution Name: {0} - Version {1}", info.UniqueName, info.Version); string newVersion; if (incrementReleaseVersion) { Logger.LogVerbose("Incrementing release version"); int release = Int32.Parse(info.Version.Substring(info.Version.LastIndexOf(".") + 1)); newVersion = $"{info.Version.Substring(0, info.Version.LastIndexOf(".") + 1)}{release + 1}"; solutionXml.UpdateSolutionVersion(folder, newVersion); } else if (!string.IsNullOrEmpty(version)) { Logger.LogInformation("Updating solution version to {0}", version); solutionXml.UpdateSolutionVersion(folder, version); newVersion = version; } else { newVersion = info.Version; } SolutionNameGenerator generator = new SolutionNameGenerator(); string zipFile; bool managed = packageType == SolutionPackager_PackageType.Managed; if (includeVersionInName) { zipFile = generator.GetZipName( info.UniqueName, newVersion, managed); } else { zipFile = generator.GetZipName( info.UniqueName, string.Empty, managed); } string zipFilePath = $"{outputFolder}\\{zipFile}"; Logger.LogVerbose("zipFile: {0}", zipFilePath); string log = string.Empty; if (!string.IsNullOrEmpty(logsDirectory)) { log = $"{logsDirectory}\\PackagerLog_{zipFile.Replace(".zip", "")}_{DateTime.Now.ToString("yyyy_MM_dd__HH_mm")}.txt"; } Logger.LogVerbose("log: {0}", log); SolutionPackager packager = new SolutionPackager( Logger, solutionPackager, zipFilePath, folder, log ); return(packager.Pack( packageType, mappingFile, treatWarningsAsErrors)); }