public SolutionApplyResult ApplySolution( string solutionName, bool importAsync, int sleepInterval, int asyncWaitTimeout ) { Logger.LogVerbose("Upgrading Solution: {0}", solutionName); if (SkipUpgrade(solutionName)) { return(new SolutionApplyResult() { Success = true, ApplySkipped = true }); } Exception syncApplyException = null; AsyncOperation asyncOperation = null; var upgradeSolutionRequest = new DeleteAndPromoteRequest { UniqueName = solutionName }; if (importAsync) { var asyncRequest = new ExecuteAsyncRequest { Request = upgradeSolutionRequest }; Logger.LogVerbose("Applying using Async Mode"); var asyncResponse = OrganizationService.Execute(asyncRequest) as ExecuteAsyncResponse; Guid asyncJobId = asyncResponse.AsyncJobId; Logger.LogInformation(string.Format("Async JobId: {0}", asyncJobId)); Logger.LogVerbose("Awaiting for Async Operation Completion"); AsyncOperationManager asyncOperationManager = new AsyncOperationManager( Logger, PollingOrganizationService); asyncOperation = asyncOperationManager.AwaitCompletion( asyncJobId, asyncWaitTimeout, sleepInterval, null); Logger.LogInformation("Async Operation completed with status: {0}", ((AsyncOperation_StatusCode)asyncOperation.StatusCode.Value).ToString()); Logger.LogInformation("Async Operation completed with message: {0}", asyncOperation.Message); } else { try { OrganizationService.Execute(upgradeSolutionRequest); } catch (Exception ex) { syncApplyException = ex; } } SolutionApplyResult result = VerifyUpgrade( solutionName, asyncOperation, syncApplyException); if (result.Success) { Logger.LogInformation("Solution Apply Completed Successfully"); } else { Logger.LogInformation("Solution Apply Failed"); } return(result); }
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 string ExportSolution( string outputFolder, SolutionExportOptions options) { Logger.LogVerbose("Exporting Solution: {0}", options.SolutionName); var solutionFile = new StringBuilder(); Solution solution = GetSolution(options.SolutionName, new ColumnSet("version")); if (solution is null) { throw new Exception($"Unable to find solution with unique name: {options.SolutionName}"); } else { Logger.LogInformation($"Exporting Solution: {options.SolutionName}, version: {solution.Version}"); } solutionFile.Append(options.SolutionName); if (options.IncludeVersionInName) { solutionFile.Append("_"); solutionFile.Append(solution.Version.Replace(".", "_")); } if (options.Managed) { solutionFile.Append("_managed"); } solutionFile.Append(".zip"); var exportSolutionRequest = new ExportSolutionRequest { Managed = options.Managed, SolutionName = options.SolutionName, ExportAutoNumberingSettings = options.ExportAutoNumberingSettings, ExportCalendarSettings = options.ExportCalendarSettings, ExportCustomizationSettings = options.ExportCustomizationSettings, ExportEmailTrackingSettings = options.ExportEmailTrackingSettings, ExportGeneralSettings = options.ExportGeneralSettings, ExportIsvConfig = options.ExportIsvConfig, ExportMarketingSettings = options.ExportMarketingSettings, ExportOutlookSynchronizationSettings = options.ExportOutlookSynchronizationSettings, ExportRelationshipRoles = options.ExportRelationshipRoles, ExportSales = options.ExportSales, TargetVersion = options.TargetVersion, RequestId = Guid.NewGuid() }; Logger.LogVerbose($"RequestId: {exportSolutionRequest.RequestId}"); //keep seperate to allow compatibility with crm2015 if (options.ExportExternalApplications) { exportSolutionRequest.ExportExternalApplications = options.ExportExternalApplications; } byte[] solutionBytes; if (options.ExportAsync) { Logger.LogInformation("Exporting Solution using Async Mode"); exportSolutionRequest.RequestName = "ExportSolutionAsync"; var asyncExportResponse = OrganizationService.Execute(exportSolutionRequest); //Guid asyncJobId = asyncResponse.AsyncJobId; Guid asyncJobId = (Guid)asyncExportResponse.Results["AsyncOperationId"]; Guid exportJobId = (Guid)asyncExportResponse.Results["ExportJobId"]; Logger.LogInformation($"AsyncOperationId: {asyncJobId}"); Logger.LogInformation($"ExportJobId: {exportJobId}"); AsyncOperationManager asyncOperationManager = new AsyncOperationManager(Logger, OrganizationService); AsyncOperation operation = asyncOperationManager.AwaitCompletion(asyncJobId, options.AsyncWaitTimeout, options.SleepInterval, null); Logger.LogInformation("Async Operation completed with status: {0}", ((AsyncOperation_StatusCode)operation.StatusCode.Value).ToString()); Logger.LogInformation("Async Operation completed with message: {0}", operation.Message); if (operation.StatusCode.Value == (int)AsyncOperation_StatusCode.Succeeded) { OrganizationRequest downloadReq = new OrganizationRequest("DownloadSolutionExportData"); downloadReq.Parameters.Add("ExportJobId", exportJobId); OrganizationResponse downloadRes = OrganizationService.Execute(downloadReq); solutionBytes = (byte[])downloadRes.Results["ExportSolutionFile"]; } else { throw new Exception($"Export of solution '{options.SolutionName}' failed: {operation.Message}"); } } else { Logger.LogInformation("Exporting Solution using Sync Mode"); var exportSolutionResponse = OrganizationService.Execute(exportSolutionRequest) as ExportSolutionResponse; solutionBytes = exportSolutionResponse.ExportSolutionFile; } string solutionFilePath = Path.Combine(outputFolder, solutionFile.ToString()); File.WriteAllBytes(solutionFilePath, solutionBytes); Logger.LogInformation($"Solution Exported to: {solutionFilePath}"); Logger.LogInformation("Solution Zip Size: {0}", FileUtilities.GetFileSize(solutionFilePath)); return(solutionFilePath); }