private void BtnImport_Click(object sender, EventArgs e) { var solutionPath = txtSolutionPathText.Text; if (string.IsNullOrEmpty(solutionPath) || solutionPath == DEFAULT_TEXT) { MessageBox.Show(MESSAGE_INCCORRECT_PATH); return; } ExecuteAsyncRequest importRequest = PrepareImportRequest ( solutionPath, cbPublishAfterImport.Checked, cbConvertToManaged.Checked, cbHoldingSolution.Checked, cbSkipProductUpdateDependencies.Checked ); RunImportRequest(importRequest); InitTimer(); }
public virtual ExecuteAsyncResponse ImportSolutionAsync(Guid importJobId, byte[] content, bool holdingSolution, bool overwriteUnmanagedCustomizations, bool publishWorkflows, bool skipProductUpdateDependencies) { Logger.Trace(CultureInfo.InvariantCulture, TraceMessageHelper.EnteredMethod, SystemTypeName, MethodBase.GetCurrentMethod().Name); if (Guid.Empty.Equals(importJobId)) { throw new ArgumentNullException(nameof(importJobId)); } if (content == null) { throw new ArgumentNullException(nameof(content)); } ExecuteAsyncRequest req = new ExecuteAsyncRequest { Request = new ImportSolutionRequest { CustomizationFile = content, HoldingSolution = holdingSolution, ImportJobId = importJobId, OverwriteUnmanagedCustomizations = overwriteUnmanagedCustomizations, PublishWorkflows = publishWorkflows, SkipProductUpdateDependencies = skipProductUpdateDependencies } }; ExecuteAsyncResponse res = (ExecuteAsyncResponse)OrganizationService.Execute(req); Logger.Trace(CultureInfo.InvariantCulture, TraceMessageHelper.ExitingMethod, SystemTypeName, MethodBase.GetCurrentMethod().Name); return(res); }
private void RunImportRequest(ExecuteAsyncRequest request) { WorkAsync(new WorkAsyncInfo { Message = MESSAGE_UPLOADING_SOLUTION, Work = (worker, args) => { args.Result = (ExecuteAsyncResponse)Service.Execute(request); }, PostWorkCallBack = (args) => { if (args.Error != null) { MessageBox.Show(args.Error.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } var result = args.Result; if (result != null) { MessageBox.Show(MESSAGE_IMPORT_STARTED); } } }); }
protected override void ProcessRecord() { base.ProcessRecord(); base.WriteVerbose(string.Format("Upgrading Solution: {0}", UniqueSolutionName)); // TODO: I think this is not necessary because you will get back an Id if you overload Guid.Empty if (ImportJobId == Guid.Empty) { ImportJobId = Guid.NewGuid(); } if (AsyncWaitTimeout == 0) { AsyncWaitTimeout = 15 * 60; base.WriteVerbose(string.Format("Setting Default AsyncWaitTimeout: {0}", AsyncWaitTimeout)); } if (SleepInterval == 0) { SleepInterval = 15; base.WriteVerbose(string.Format("Setting Default SleepInterval: {0}", SleepInterval)); } base.WriteCommandDetail(string.Format("ImportJobId {0}", ImportJobId)); var upgradeSolutionRequest = new DeleteAndPromoteRequest { UniqueName = UniqueSolutionName, RequestId = ImportJobId }; if (ImportAsync) { var asyncRequest = new ExecuteAsyncRequest { Request = upgradeSolutionRequest, RequestId = ImportJobId }; var asyncResponse = OrganizationService.Execute(asyncRequest) as ExecuteAsyncResponse; Guid asyncJobId = asyncResponse.AsyncJobId; WriteObject(asyncJobId); if (WaitForCompletion) { AwaitCompletion(asyncJobId); } } else { OrganizationService.Execute(upgradeSolutionRequest); } base.WriteVerbose(string.Format("{0} Upgrade Completed {1}", UniqueSolutionName, ImportJobId)); }
protected override void ProcessRecord() { base.ProcessRecord(); base.WriteVerbose(string.Format("Upgrading Solution: {0}", UniqueSolutionName)); if (AsyncWaitTimeout == 0) { AsyncWaitTimeout = 15 * 60; base.WriteVerbose(string.Format("Setting Default AsyncWaitTimeout: {0}", AsyncWaitTimeout)); } if (SleepInterval == 0) { SleepInterval = 15; base.WriteVerbose(string.Format("Setting Default SleepInterval: {0}", SleepInterval)); } var upgradeSolutionRequest = new DeleteAndPromoteRequest { UniqueName = UniqueSolutionName }; if (ImportAsync) { var asyncRequest = new ExecuteAsyncRequest { Request = upgradeSolutionRequest }; base.WriteVerbose("Applying using Async Mode"); var asyncResponse = OrganizationService.Execute(asyncRequest) as ExecuteAsyncResponse; Guid asyncJobId = asyncResponse.AsyncJobId; base.WriteVerbose(string.Format("Async JobId: {0}", asyncJobId)); WriteObject(asyncJobId); if (WaitForCompletion) { base.WriteVerbose("Waiting for completion"); AwaitCompletion(asyncJobId); } } else { OrganizationService.Execute(upgradeSolutionRequest); } base.WriteVerbose(string.Format("{0} Upgrade Completed", UniqueSolutionName)); VerifyUpgrade(); }
protected override void ProcessRecord() { base.ProcessRecord(); base.WriteVerbose(string.Format("Importing Solution: {0}", SolutionFilePath)); // TODO: I think this is not necessary because you will get back an Id if you overload Guid.Empty if (ImportJobId == Guid.Empty) { ImportJobId = Guid.NewGuid(); } base.WriteVerbose(string.Format("ImportJobId {0}", ImportJobId)); byte[] solutionBytes = File.ReadAllBytes(SolutionFilePath); var importSolutionRequest = new ImportSolutionRequest { CustomizationFile = solutionBytes, PublishWorkflows = PublishWorkflows, ConvertToManaged = ConvertToManaged, OverwriteUnmanagedCustomizations = OverwriteUnmanagedCustomizations, SkipProductUpdateDependencies = SkipProductUpdateDependencies, ImportJobId = ImportJobId, RequestId = ImportJobId, HoldingSolution = HoldingSolution }; if (ImportAsync) { var asyncRequest = new ExecuteAsyncRequest { Request = importSolutionRequest, RequestId = ImportJobId }; var asyncResponse = OrganizationService.Execute(asyncRequest) as ExecuteAsyncResponse; Guid asyncJobId = asyncResponse.AsyncJobId; WriteObject(asyncJobId); if (WaitForCompletion) { AwaitCompletion(asyncJobId); } } else { OrganizationService.Execute(importSolutionRequest); } base.WriteVerbose(string.Format("{0} Imported Completed {1}", SolutionFilePath, ImportJobId)); }
private Guid ImportSolutionInTargetOrg(ITracingService tracingService, byte[] fileContent, EntityCollection credentials, string username, string password) { Guid asyncOperationId = Guid.Empty; IOrganizationService targetOrganizationService = null; //AliasedValue usernameAliasVal = credentials.Entities[0].GetAttributeValue<AliasedValue>("aa.devops_userid"); //AliasedValue passwordAliasVal = credentials.Entities[0].GetAttributeValue<AliasedValue>("aa.devops_userpassword"); AliasedValue orgSvcAliasVal = credentials.Entities[0].GetAttributeValue <AliasedValue>("aa.devops_orgserviceurl"); //string userName = string.Empty; //string password = string.Empty; string orgSvcUrl = string.Empty; if (orgSvcAliasVal != null) { //userName = usernameAliasVal.Value.ToString(); //password = passwordAliasVal.Value.ToString(); orgSvcUrl = orgSvcAliasVal.Value.ToString(); } ClientCredentials clientCredentials = new ClientCredentials(); clientCredentials.UserName.UserName = username; clientCredentials.UserName.Password = password; ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; tracingService.Trace($"Trying to create new OrganizationServiceProxy"); targetOrganizationService = new OrganizationServiceProxy(new Uri(orgSvcUrl), null, clientCredentials, null); if (targetOrganizationService != null) { tracingService.Trace($"Starting import in target organization"); var request = new ImportSolutionRequest() { CustomizationFile = fileContent, OverwriteUnmanagedCustomizations = OverWrite }; var requestAsync = new ExecuteAsyncRequest { Request = request }; var asyncResp = (ExecuteAsyncResponse)targetOrganizationService.Execute(requestAsync); tracingService.Trace($"Executed the Import Request"); asyncOperationId = asyncResp.AsyncJobId; } return(asyncOperationId); }
static void Main(string[] args) { System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12; Console.WriteLine("Please check the app.config to add credentials and organization url"); string connectionString = ConfigurationManager.ConnectionStrings["CrmDefaultConnection"].ToString(); var serviceClient = new CrmServiceClient(connectionString); serviceClient.OrganizationServiceProxy.Timeout = new TimeSpan(1, 30, 0); if (!serviceClient.IsReady) { throw new Exception("Cannot connect to organization!, Please check the app.config to add credentials and organization url"); } Console.WriteLine("Connected to {0}", serviceClient.ConnectedOrgFriendlyName); Console.WriteLine("Do you want to import the solution Synchronously or Asynchronously ?\n 1 - Sync \n 2 - Async"); string input = Console.ReadLine(); double d; if (Double.TryParse(input, out d)) { if (d == 1)//Synchronous { Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); var importSolutionResponse = (ImportSolutionResponse)serviceClient.Execute(ImportSolution(serviceClient)); var est = importSolutionResponse.Results; stopWatch.Stop(); Console.WriteLine("RunTime " + stopWatch.Elapsed); Console.ReadKey(); } else if (d == 2)//Asynchronous { Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); ExecuteAsyncRequest request = new ExecuteAsyncRequest(); request.Request = ImportSolution(serviceClient); ExecuteAsyncResponse response = (ExecuteAsyncResponse)serviceClient.Execute(request); stopWatch.Stop(); Console.WriteLine("RunTime " + stopWatch.Elapsed); Console.ReadKey(); } else { Console.WriteLine("Invalid option - bye"); Console.ReadKey(); } } }
private static ExecuteAsyncRequest PrepareImportRequest(string filePath, params bool[] values) { //ParameterCollection parameterCollection = new ParameterCollection(); //parameterCollection.Add(new System.Collections.Generic.KeyValuePair<string, object>("name", "test")); ExecuteAsyncRequest request = new ExecuteAsyncRequest { Request = new ImportSolutionRequest { CustomizationFile = File.ReadAllBytes(filePath), OverwriteUnmanagedCustomizations = true, PublishWorkflows = values[0], ConvertToManaged = values[1], HoldingSolution = values[2], SkipProductUpdateDependencies = values[3] } }; return(request); }
public virtual ExecuteAsyncResponse DeleteAndPromoteSolutionAsync(string uniqueName) { Logger.Trace(CultureInfo.InvariantCulture, TraceMessageHelper.EnteredMethod, SystemTypeName, MethodBase.GetCurrentMethod().Name); if (string.IsNullOrWhiteSpace(uniqueName)) { throw new ArgumentNullException(nameof(uniqueName)); } ExecuteAsyncRequest req = new ExecuteAsyncRequest { Request = new DeleteAndPromoteRequest { UniqueName = uniqueName } }; ExecuteAsyncResponse res = (ExecuteAsyncResponse)OrganizationServiceContext.Execute(req); Logger.Trace(CultureInfo.InvariantCulture, TraceMessageHelper.ExitingMethod, SystemTypeName, MethodBase.GetCurrentMethod().Name); return(res); }
private Models.ImportSolutionRequest ImportSolutionInner(Parameters @params) { Guid importJobId = Guid.NewGuid(); var importSolutionRequest = new ExecuteAsyncRequest() { Request = new Microsoft.Crm.Sdk.Messages.ImportSolutionRequest() { ImportJobId = importJobId, ConvertToManaged = @params.ImportManaged, OverwriteUnmanagedCustomizations = @params.ImportOverwrite, SkipProductUpdateDependencies = @params.ImportDependencies, PublishWorkflows = @params.ImportPublishWorkflows, CustomizationFile = File.ReadAllBytes(@params.CustomizationFile) } }; return(new Models.ImportSolutionRequest() { ImportJobId = importJobId, ExecuteAsyncResponse = solutionPackagerControl.Service.Execute(importSolutionRequest) as ExecuteAsyncResponse }); }
private static Guid ImportSolutionAsyncRequest( IOrganizationService service, byte[] data, bool overwriteUnmanagedCustomizations = true, bool migrateAsHold = false, bool publishWorkflows = true) { ImportSolutionRequest importRequest = new ImportSolutionRequest() { CustomizationFile = data, OverwriteUnmanagedCustomizations = overwriteUnmanagedCustomizations, HoldingSolution = migrateAsHold, PublishWorkflows = publishWorkflows, }; ExecuteAsyncRequest asyncRequest = new ExecuteAsyncRequest() { Request = importRequest, }; var asyncResponse = (ExecuteAsyncResponse)service.Execute(asyncRequest); var asyncJobId = asyncResponse.AsyncJobId; return(asyncJobId); }
public ImportSolutionsResponse ImportSolutions(Dictionary <string, byte[]> solutionFiles, LogController controller) { var response = new ImportSolutionsResponse(); var xrmService = XrmRecordService.XrmService; bool asynch = xrmService.SupportsExecuteAsynch; controller.LogLiteral($"Loading Active {xrmService.GetEntityCollectionName(Entities.duplicaterule)}"); var duplicateRules = xrmService.RetrieveAllAndClauses(Entities.duplicaterule, new[] { new ConditionExpression(Fields.duplicaterule_.statecode, ConditionOperator.Equal, OptionSets.DuplicateDetectionRule.Status.Active) }, new string[0]); foreach (var solutionFile in solutionFiles) { if (!response.Success) { break; } try { controller.LogLiteral( $"Importing Solution {solutionFile.Key} Into {XrmRecordService.XrmRecordConfiguration?.ToString()}"); var importId = Guid.NewGuid(); var req = new ImportSolutionRequest(); req.ImportJobId = importId; req.CustomizationFile = solutionFile.Value; req.PublishWorkflows = true; req.OverwriteUnmanagedCustomizations = true; var finished = new Processor(); if (!asynch) { try { var extraService = new XrmService(xrmService.XrmConfiguration, new LogController(), xrmService.ServiceFactory); var monitoreProgressThread = new Thread(() => DoProgress(importId, controller.GetLevel2Controller(), finished, extraService, asynch, solutionFile.Key, response)); monitoreProgressThread.IsBackground = true; monitoreProgressThread.Start(); xrmService.Execute(req); ProcessCompletedSolutionImportJob(response, xrmService, importId); } finally { lock (_lockObject) finished.Completed = true; } } else { var asynchRequest = new ExecuteAsyncRequest { Request = req }; xrmService.Execute(asynchRequest); DoProgress(importId, controller.GetLevel2Controller(), finished, xrmService, asynch, solutionFile.Key, response); } } catch (FaultException <OrganizationServiceFault> ex) { if (ex.Detail != null && ex.Detail.InnerFault != null && ex.Detail.InnerFault.InnerFault != null) { throw new Exception(string.Format("Error Importing Solution {0}\n{1}\n{2}", solutionFile, ex.Message, ex.Detail.InnerFault.InnerFault.Message), ex); } else { throw new Exception( string.Format("Error Importing Solution {0}\n{1}", solutionFile, ex.Message), ex); } } catch (Exception ex) { throw new Exception(string.Format("Error Importing Solution {0}", solutionFile), ex); } } controller.TurnOffLevel2(); if (response.Success) { controller.LogLiteral("Publishing Customisations"); xrmService.Publish(); } controller.LogLiteral($"Checking Deactivated {xrmService.GetEntityCollectionName(Entities.duplicaterule)}"); duplicateRules = xrmService.Retrieve(Entities.duplicaterule, duplicateRules.Select(e => e.Id), new[] { Fields.duplicaterule_.statecode, Fields.duplicaterule_.name }); foreach (var rule in duplicateRules) { if (rule.GetOptionSetValue(Fields.duplicaterule_.statecode) == OptionSets.DuplicateDetectionRule.Status.Inactive) { controller.LogLiteral($"Republishing {xrmService.GetEntityLabel(Entities.duplicaterule)} '{rule.GetStringField(Fields.duplicaterule_.name)}'"); xrmService.Execute(new PublishDuplicateRuleRequest() { DuplicateRuleId = rule.Id }); } } return(response); }
private bool DoImportSolutionAsync(ImportSolutionRequest impSolReq, ref Exception ex) { container.StartSection(MethodBase.GetCurrentMethod().Name); // Code cred to Wael Hamze // http://waelhamze.com/2013/11/17/asynchronous-solution-import-dynamics-crm-2013/ var result = false; var asyncRequest = new ExecuteAsyncRequest() { Request = impSolReq }; var asyncResponse = container.Execute(asyncRequest) as ExecuteAsyncResponse; var asyncJobId = asyncResponse.AsyncJobId; var end = DateTime.MaxValue; var importStatus = -1; var progress = 0; var statustext = "Submitting job"; SendLineUpdate(container, $"Import status: {statustext}"); while (end >= DateTime.Now) { Entity cdAsyncOperation = null; try { cdAsyncOperation = container.Retrieve(SystemJob.EntityName, asyncJobId, new ColumnSet(SystemJob.PrimaryKey, SystemJob.Status, SystemJob.StatusReason, SystemJob.Message, SystemJob.Friendlymessage)); } catch (Exception asyncex) { cdAsyncOperation = null; container.Log(asyncex); container.EndSection(); // Ending section started by Retrieve above to prevent indentation inflation } if (cdAsyncOperation != null) { container.Attribute(SystemJob.StatusReason).On(cdAsyncOperation).ToString(); statustext = container.Attribute(SystemJob.StatusReason).On(cdAsyncOperation).ToString(); var newStatus = cdAsyncOperation.GetAttribute(SystemJob.StatusReason, new OptionSetValue()).Value; if (newStatus != importStatus) { importStatus = newStatus; if (end.Equals(DateTime.MaxValue) && importStatus != (int)SystemJob.StatusReason_OptionSet.Waiting) { end = timeout > 0 ? DateTime.Now.AddMinutes(timeout) : DateTime.Now.AddMinutes(2); SendLineUpdate(container, "Import job picked up at {0}", DateTime.Now); container.Log("Timout until: {0}", end.ToString("HH:mm:ss.fff")); SendLine(container, "Import status: {0}", statustext); } SendLineUpdate(container, "Import status: {0}", statustext); container.Log("Import message:\n{0}", cdAsyncOperation.GetAttribute(SystemJob.Message, "<none>")); if (importStatus == (int)SystemJob.StatusReason_OptionSet.Succeeded) { // Succeeded result = true; break; } else if (importStatus == (int)SystemJob.StatusReason_OptionSet.Pausing || importStatus == (int)SystemJob.StatusReason_OptionSet.Canceling || importStatus == (int)SystemJob.StatusReason_OptionSet.Failed || importStatus == (int)SystemJob.StatusReason_OptionSet.Canceled) { // Error statuses var friendlymessage = cdAsyncOperation.GetAttribute(SystemJob.Friendlymessage, ""); SendLine(container, "Message: {0}", friendlymessage); if (friendlymessage == "Access is denied.") { SendLine(container, "When importing to onprem environment, the async service user must be granted read/write permission to folder:"); SendLine(container, " C:\\Program Files\\Microsoft Dynamics CRM\\CustomizationImport"); } else { var message = cdAsyncOperation.GetAttribute(SystemJob.Message, "<none>"); message = ExtractErrorMessage(message); if (!string.IsNullOrWhiteSpace(message) && !message.Equals(friendlymessage, StringComparison.InvariantCultureIgnoreCase)) { SendLine(container, "Detailed message: \n{0}", message); } else { SendLine(container, "See log file for technical details."); } } container.Attribute(SystemJob.Status).On(cdAsyncOperation).ToString(); ex = new Exception($"Solution Import Failed: {container.Attribute(SystemJob.Status).On(cdAsyncOperation).ToString()} - {container.Attribute(SystemJob.StatusReason).On(cdAsyncOperation).ToString()}"); break; } } } System.Threading.Thread.Sleep(1000); if (importStatus == 20) { // In progress, read percent try { var job = container.Retrieve(ImportJob.EntityName, impSolReq.ImportJobId, new ColumnSet(ImportJob.Progress)); if (job != null) { var newProgress = Convert.ToInt32(Math.Round(job.GetAttribute(ImportJob.Progress, 0D))); if (newProgress > progress) { progress = newProgress; SendStatus(-1, -1, 100, progress); SendLineUpdate(container, "Import status: {0} - {1}%", statustext, progress); } } } catch (Exception jobex) { // We probably tried before the job was created if (jobex.Message.ToUpperInvariant().Contains("DOES NOT EXIST")) { container.Log("Importjob not created yet or already deleted"); } else { container.Log(jobex); } container.EndSection(); // Ending section started by Retrieve above to prevent indentation inflation } } } if (end < DateTime.Now) { SendLine(container, "Import timed out."); } SendStatus(-1, -1, 100, 0); container.EndSection(); 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 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); }
/// <summary> /// Method import master solution to deployment instance /// </summary> /// <param name="serviceProxy">organization service proxy</param> /// <param name="solutionFile">solution file</param> /// <param name="uri">URL of Instance</param> public void ImportSolution(OrganizationServiceProxy serviceProxy, SolutionFileInfo solutionFile, Uri uri) { string solutionImportPath = solutionFile.SolutionFilePathManaged ?? solutionFile.SolutionFilePath; Singleton.SolutionFileInfoInstance.WebJobsLog.AppendLine(" Started importing solution to Organization " + uri + "<br>"); Console.WriteLine("Started importing solution to Organization " + uri); byte[] fileBytes = File.ReadAllBytes(solutionImportPath); ImportSolutionRequest impSolReq = new ImportSolutionRequest() { CustomizationFile = fileBytes, ImportJobId = Guid.NewGuid(), OverwriteUnmanagedCustomizations = true, SkipProductUpdateDependencies = true, PublishWorkflows = false, }; ExecuteAsyncRequest importRequest = new ExecuteAsyncRequest() { Request = impSolReq }; ExecuteAsyncResponse importRequestResponse = (ExecuteAsyncResponse)serviceProxy.Execute(importRequest); string solutionImportResult = string.Empty; while (solutionImportResult == string.Empty) { Guid asyncJobId = importRequestResponse.AsyncJobId; Entity job = (Entity)serviceProxy.Retrieve("asyncoperation", asyncJobId, new ColumnSet(new string[] { "asyncoperationid", "statuscode", "message" })); int jobStatusCode = ((OptionSetValue)job["statuscode"]).Value; switch (jobStatusCode) { ////Success case 30: solutionImportResult = "success"; Singleton.SolutionFileInfoInstance.WebJobsLog.AppendLine(" Solution imported successfully to the Organization " + uri + "<br>"); Console.WriteLine("Solution imported successfully to the Organization " + uri); solutionFile.Solution[Constants.SourceControlQueueAttributeNameForStatus] = Constants.SourceControlQueueImportSuccessfulStatus; solutionFile.Solution["syed_webjobs"] = Singleton.SolutionFileInfoInstance.WebJobs(); solutionFile.Update(); break; ////Pausing case 21: solutionImportResult = "pausing"; Singleton.SolutionFileInfoInstance.WebJobsLog.AppendLine(string.Format(" Solution Import Pausing: {0}{1}", jobStatusCode, job["message"]) + "<br>"); Console.WriteLine(string.Format("Solution Import Pausing: {0} {1}", jobStatusCode, job["message"])); break; ////Cancelling case 22: solutionImportResult = "cancelling"; Singleton.SolutionFileInfoInstance.WebJobsLog.AppendLine(string.Format("Solution Import Cancelling: {0}{1}", jobStatusCode, job["message"]) + "<br>"); Console.WriteLine(string.Format("Solution Import Cancelling: {0}{1}", jobStatusCode, job["message"])); break; ////Failed case 31: solutionImportResult = "failed"; Singleton.SolutionFileInfoInstance.WebJobsLog.AppendLine(string.Format("Solution Import Failed: {0}{1}", jobStatusCode, job["message"]) + "<br>"); Console.WriteLine(string.Format("Solution Import Failed: {0}{1}", jobStatusCode, job["message"])); break; ////Cancelled case 32: Console.WriteLine(string.Format("Solution Import Cancelled: {0}{1}", jobStatusCode, job["message"])); Singleton.SolutionFileInfoInstance.WebJobsLog.AppendLine(string.Format("Solution Import Cancelled: {0}{1}", jobStatusCode, job["message"])); throw new Exception(string.Format("Solution Import Cancelled: {0}{1}", jobStatusCode, job["message"])); default: break; } } if (solutionImportResult == "success") { this.PublishAllCustomizationChanges(serviceProxy, solutionFile); solutionFile.Solution[Constants.SourceControlQueueAttributeNameForStatus] = Constants.SourceControlQueuePublishSuccessfulStatus; } solutionFile.Solution.Attributes["syed_webjobs"] = Singleton.SolutionFileInfoInstance.WebJobs(); solutionFile.Update(); }
public void ImportSolutionArchive(string archivePath, ImportSettings settings) { try { importPath = archivePath; //sets the global variable for the import path var request = new ImportSolutionRequest { ConvertToManaged = settings.ConvertToManaged, CustomizationFile = File.ReadAllBytes(archivePath), OverwriteUnmanagedCustomizations = settings.OverwriteUnmanagedCustomizations, PublishWorkflows = settings.Activate, ImportJobId = settings.ImportId }; if (settings.MajorVersion >= 6) { var requestAsync = new ExecuteAsyncRequest { Request = request }; innerService.Execute(requestAsync); bool isfinished = false; do { try { var job = innerService.Retrieve("importjob", settings.ImportId, new ColumnSet(true)); if (job.Contains("completedon")) { isfinished = true; } } catch { } Thread.Sleep(2000); } while (isfinished == false); } else { innerService.Execute(request); } } catch (FaultException <OrganizationServiceFault> error) { throw new Exception("An error while importing archive: " + error.Message); } finally { if (settings.DownloadLog) { string filePath = DownloadLogFile(importPath, settings); if (MessageBox.Show("Do you want to open the log file now?\r\n\r\nThe file will also be available on disk: " + filePath, "Question", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) { Process.Start("Excel.exe", "\"" + filePath + "\""); } } } }
private void ImportSolution(string solutionPath) { _trace.WriteLine("Importing solution '{0}'...", solutionPath); var solutionBytes = File.ReadAllBytes(solutionPath); var request = new ImportSolutionRequest(); request.OverwriteUnmanagedCustomizations = true; request.PublishWorkflows = true; request.CustomizationFile = solutionBytes; request.ImportJobId = Guid.NewGuid(); var asyncExecute = new ExecuteAsyncRequest() { Request = request }; var response = (ExecuteAsyncResponse)_service.Execute(asyncExecute); var asyncoperationid = response.AsyncJobId; var importComplete = false; var importStartedOn = DateTime.Now; var importError = String.Empty; do { try { if (DateTime.Now.Subtract(importStartedOn).Minutes > 15) { throw new SparkleTaskException(SparkleTaskException.ExceptionTypes.IMPORT_ERROR, "Timeout whilst uploading solution\nThe import process has timed out after 15 minutes."); } // Query the job until completed var job = _service.Retrieve("asyncoperation", asyncoperationid, new ColumnSet(new System.String[] { "statuscode", "message", "friendlymessage" })); var statuscode = job.GetAttributeValue <OptionSetValue>("statuscode"); switch (statuscode.Value) { case 30: importComplete = true; importError = ""; break; case 32: // Cancelled case 31: importComplete = true; importError = job.GetAttributeValue <string>("message") + "\n" + job.GetAttributeValue <string>("friendlymessage"); break; } _trace.Write("."); } catch { // The import job can be locked or not yet created // so don't do anything and just wait... } Thread.Sleep(new TimeSpan(0, 0, 2)); }while (!importComplete); if (!string.IsNullOrEmpty(importError)) { throw new SparkleTaskException(SparkleTaskException.ExceptionTypes.IMPORT_ERROR, importError); } _trace.WriteLine("\nSolution Import Completed. Now publishing...."); // Publish var publishRequest = new PublishAllXmlRequest(); var publishResponse = (PublishAllXmlResponse)_service.Execute(publishRequest); _trace.WriteLine("Solution Publish Completed"); }
public void ImportSolutionArchive(string archivePath, ImportSettings settings) { try { importPath = archivePath; //sets the global variable for the import path var request = new ImportSolutionRequest { ConvertToManaged = settings.ConvertToManaged, CustomizationFile = File.ReadAllBytes(archivePath), OverwriteUnmanagedCustomizations = settings.OverwriteUnmanagedCustomizations, PublishWorkflows = settings.Activate, ImportJobId = settings.ImportId }; if (settings.MajorVersion >= 6) { var requestAsync = new ExecuteAsyncRequest { Request = request }; innerService.Execute(requestAsync); bool isfinished = false; do { try { var job = innerService.Retrieve("importjob", settings.ImportId, new ColumnSet(true)); if (job.Contains("completedon")) { isfinished = true; } } catch { } Thread.Sleep(2000); } while (isfinished == false); } else { innerService.Execute(request); } } catch (FaultException<OrganizationServiceFault> error) { throw new Exception("An error while importing archive: " + error.Message); } finally { if (settings.DownloadLog) { string filePath = DownloadLogFile(importPath, settings); if (MessageBox.Show("Do you want to open the log file now?\r\n\r\nThe file will also be available on disk: " + filePath, "Question", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) { Process.Start("Excel.exe", "\"" + filePath + "\""); } } } }
/// <summary> /// source: https://community.dynamics.com/crm/b/tsgrdcrmblog/archive/2014/03/06/microsoft-dynamics-crm-2013-application-lifetime-management-part-2 /// </summary> public void Import(string solutionFilename, bool importAsync = true) { var solutionFileBytes = File.ReadAllBytes(solutionFilename); var importSolutionRequest = new ImportSolutionRequest { CustomizationFile = solutionFileBytes, PublishWorkflows = true, ImportJobId = new Guid(), OverwriteUnmanagedCustomizations = true }; if (importAsync) { var asyncRequest = new ExecuteAsyncRequest { Request = importSolutionRequest }; var asyncResponse = OrganizationService.Execute(asyncRequest) as ExecuteAsyncResponse; Guid?asyncJobId = asyncResponse.AsyncJobId; var end = DateTime.Now.AddMinutes(CrmParameter.ConnectionTimeOutMinutes); bool finished = false; while (!finished) { // Wait for 15 Seconds to prevent us overloading the server with too many requests Thread.Sleep(15 * 1000); if (end < DateTime.Now) { throw new Exception(($"Solution import has timed out: {CrmParameter.ConnectionTimeOutMinutes} minutes")); } Entity asyncOperation; try { asyncOperation = OrganizationService.Retrieve("asyncoperation", asyncJobId.Value, new ColumnSet("asyncoperationid", Constant.Entity.StatusCode, "message")); } catch (Exception e) { /* Unfortunately CRM Online seems to lock up the application when importing * Large Solutions, and thus it generates random errors. Mainly they are * SQL Client errors, but we can't guarantee this so we just catch them and report to user * then continue on. */ MessageLogger?.Invoke(this, $"{e.Message}"); continue; } var statusCode = asyncOperation.GetAttributeValue <OptionSetValue>(Constant.Entity.StatusCode).Value; var message = asyncOperation.GetAttributeValue <string>("message"); // Succeeded if (statusCode == 30) { finished = true; break; } // Pausing // Canceling // Failed // Canceled if (statusCode == 21 || statusCode == 22 || statusCode == 31 || statusCode == 32) { throw new Exception($"Solution Import Failed: {statusCode} {message}"); } } } else { var response = (ImportSolutionResponse)OrganizationService.Execute(importSolutionRequest); } }
protected override void ProcessRecord() { base.ProcessRecord(); base.WriteVerbose(string.Format("Importing Solution: {0}", SolutionFilePath)); CrmConnection connection = CrmConnection.Parse(connectionString); if (importJobId == Guid.Empty) { ImportJobId = Guid.NewGuid(); } base.WriteVerbose(string.Format("ImportJobId {0}", ImportJobId)); using (OrganizationService service = new OrganizationService(connection)) { byte[] solutionBytes = File.ReadAllBytes(solutionFilePath); ImportSolutionRequest importSolutionRequest = new ImportSolutionRequest() { CustomizationFile = solutionBytes, PublishWorkflows = publishWorkflows, ConvertToManaged = convertToManaged, OverwriteUnmanagedCustomizations = overwriteUnmanagedCustomizations, SkipProductUpdateDependencies = skipProductUpdateDependencies, ImportJobId = ImportJobId, RequestId = ImportJobId }; if (importAsync) { Guid asyncJobId; ExecuteAsyncRequest asyncRequest = new ExecuteAsyncRequest() { Request = importSolutionRequest, RequestId = ImportJobId }; ExecuteAsyncResponse asyncResponse = service.Execute(asyncRequest) as ExecuteAsyncResponse; asyncJobId = asyncResponse.AsyncJobId; WriteObject(asyncJobId); if (waitForCompletion) { DateTime end = DateTime.Now.AddSeconds(asyncWaitTimeout); bool completed = false; while (!completed) { if (end < DateTime.Now) { throw new Exception(string.Format("Import Timeout Exceeded: {0}", asyncWaitTimeout)); } Thread.Sleep(SleepInterval * 1000); AsyncOperation asyncOperation; try { asyncOperation = service.Retrieve("asyncoperation", asyncJobId, new ColumnSet("asyncoperationid", "statuscode", "message")).ToEntity <AsyncOperation>(); } catch (Exception ex) { base.WriteWarning(ex.Message); continue; } switch (asyncOperation.StatusCode.Value) { //Succeeded case 30: completed = true; break; //Pausing //Canceling //Failed //Canceled case 21: case 22: case 31: case 32: throw new Exception(string.Format("Solution Import Failed: {0} {1}", asyncOperation.StatusCode.Value, asyncOperation.Message)); default: break; } } } } else { ImportSolutionResponse importSolutionResponse = service.Execute(importSolutionRequest) as ImportSolutionResponse; } base.WriteVerbose(string.Format("{0} Imported Completed {1}", SolutionFilePath, importJobId)); } }
protected override void ProcessRecord() { base.ProcessRecord(); base.WriteVerbose(string.Format("Importing Solution: {0}", SolutionFilePath)); // TODO: I think this is not necessary because you will get back an Id if you overload Guid.Empty if (ImportJobId == Guid.Empty) { ImportJobId = Guid.NewGuid(); } if (AsyncWaitTimeout == 0) { AsyncWaitTimeout = 15 * 60; base.WriteVerbose(string.Format("Setting Default AsyncWaitTimeout: {0}", AsyncWaitTimeout)); } if (SleepInterval == 0) { SleepInterval = 15; base.WriteVerbose(string.Format("Setting Default SleepInterval: {0}", SleepInterval)); } base.WriteVerbose(string.Format("ImportJobId {0}", ImportJobId)); byte[] solutionBytes = File.ReadAllBytes(SolutionFilePath); var importSolutionRequest = new ImportSolutionRequest { CustomizationFile = solutionBytes, PublishWorkflows = PublishWorkflows, ConvertToManaged = ConvertToManaged, OverwriteUnmanagedCustomizations = OverwriteUnmanagedCustomizations, SkipProductUpdateDependencies = SkipProductUpdateDependencies, ImportJobId = ImportJobId, RequestId = ImportJobId, HoldingSolution = HoldingSolution }; if (ImportAsync) { base.WriteVerbose(string.Format("Importing solution in Async Mode")); var asyncRequest = new ExecuteAsyncRequest { Request = importSolutionRequest, RequestId = ImportJobId }; var asyncResponse = OrganizationService.Execute(asyncRequest) as ExecuteAsyncResponse; Guid asyncJobId = asyncResponse.AsyncJobId; WriteObject(asyncJobId); if (WaitForCompletion) { base.WriteVerbose(string.Format("Awaiting for Async Operation Completion")); AwaitCompletion(asyncJobId); } } else { base.WriteVerbose(string.Format("Importing solution in Sync Mode")); try { OrganizationService.Execute(importSolutionRequest); } catch (Exception ex) { if (WaitForCompletion) { base.WriteWarning(ex.Message); base.WriteVerbose("Exception Handled. Attempting to Wait for ImportJob to Complete."); AwaitImportJob(); } else { throw ex; } } } base.WriteVerbose(string.Format("{0} Imported Completed {1}", SolutionFilePath, ImportJobId)); }
private bool DoImportSolutionAsync(ImportSolutionRequest impSolReq, ref Exception ex) { log.StartSection(MethodBase.GetCurrentMethod().Name); // Code cred to Wael Hamze // http://waelhamze.com/2013/11/17/asynchronous-solution-import-dynamics-crm-2013/ var result = false; ExecuteAsyncRequest asyncRequest = new ExecuteAsyncRequest() { Request = impSolReq }; ExecuteAsyncResponse asyncResponse = crmsvc.Execute(asyncRequest) as ExecuteAsyncResponse; var asyncJobId = asyncResponse.AsyncJobId; DateTime end = timeout > 0 ? DateTime.Now.AddMinutes(timeout) : DateTime.Now.AddMinutes(2); log.Log("Timout until: {0}", end.ToString("HH:mm:ss.fff")); var importStatus = -1; var progress = 0; var statustext = "Submitting job"; SendLineUpdate("Import status: {0}", statustext); while (end >= DateTime.Now) { CintDynEntity cdAsyncOperation = null; try { cdAsyncOperation = CintDynEntity.Retrieve("asyncoperation", asyncJobId, new ColumnSet("asyncoperationid", "statecode", "statuscode", "message", "friendlymessage"), crmsvc, log); } catch (Exception asyncex) { cdAsyncOperation = null; log.Log(asyncex); log.EndSection(); // Ending section started by Retrieve above to prevent indentation inflation } if (cdAsyncOperation != null) { statustext = cdAsyncOperation.PropertyAsString("statuscode", "?", false, false); var newStatus = cdAsyncOperation.Property("statuscode", new OptionSetValue()).Value; if (newStatus != importStatus) { importStatus = newStatus; SendLineUpdate("Import status: {0}", statustext); log.Log("Import message:\n{0}", cdAsyncOperation.Property("message", "<none>")); if (importStatus == 30) { // Succeeded result = true; break; } else if (importStatus == 21 || importStatus == 22 || importStatus == 31 || importStatus == 32) { // Error statuses var friendlymessage = cdAsyncOperation.Property("friendlymessage", ""); SendLine("Message: {0}", friendlymessage); if (friendlymessage == "Access is denied.") { SendLine("When importing to onprem environment, the async service user must be granted read/write permission to folder:"); SendLine(" C:\\Program Files\\Microsoft Dynamics CRM\\CustomizationImport"); } else { var message = cdAsyncOperation.Property("message", "<none>"); message = ExtractErrorMessage(message); if (!string.IsNullOrWhiteSpace(message) && !message.Equals(friendlymessage, StringComparison.InvariantCultureIgnoreCase)) { SendLine("Detailed message: \n{0}", message); } else { SendLine("See log file for technical details."); } } ex = new Exception(string.Format("Solution Import Failed: {0} - {1}", cdAsyncOperation.PropertyAsString("statecode", "?", false, false), cdAsyncOperation.PropertyAsString("statuscode", "?", false, false))); break; } } } System.Threading.Thread.Sleep(1000); if (importStatus == 20) { // In progress, read percent try { var job = CintDynEntity.Retrieve("importjob", impSolReq.ImportJobId, new ColumnSet("progress"), crmsvc, log); if (job != null) { var newProgress = job.Property("progress", 0D); if (newProgress > progress + 5) { progress = Convert.ToInt32(Math.Round(newProgress)); SendStatus(-1, -1, 100, progress); SendLineUpdate("Import status: {0} - {1}%", statustext, progress); } } } catch (Exception jobex) { // We probably tried before the job was created if (jobex.Message.ToUpperInvariant().Contains("DOES NOT EXIST")) { log.Log("Importjob not created yet or already deleted"); } else { log.Log(jobex); } log.EndSection(); // Ending section started by Retrieve above to prevent indentation inflation } } } if (end < DateTime.Now) { SendLine("Import timed out."); } SendStatus(-1, -1, 100, 0); log.EndSection(); return(result); }
/// <summary> /// Imports a Dynamics CRM solution to a Dynamics CRM organization. /// </summary> /// <returns>An <seealso cref="ImportSolutionResult"/> object</returns> public override Result Execute() { if (this.SolutionFileStream == null) { throw new ArgumentNullException(nameof(this.SolutionFileStream)); } var buffer = new byte[(int)this.SolutionFileStream.Length]; this.SolutionFileStream.Read(buffer, 0, buffer.Length); Solution zipSolution = this.ReadSolutionXmlFromZip(this.SolutionFileStream); bool startImport = this.CompareSolutionVersion(zipSolution.GetVersion(), zipSolution.UniqueName); if (!startImport) { return(new Result() { Success = false }); } Entity job; try { var importSolutionRequest = new ImportSolutionRequest { HoldingSolution = this.HoldingSolution, ConvertToManaged = this.ConvertToManaged, CustomizationFile = buffer, ImportJobId = this.ImportJobId, OverwriteUnmanagedCustomizations = this.OverwriteUnmanagedCustomizations, PublishWorkflows = this.PublishWorkflows, SkipProductUpdateDependencies = this.SkipProductUpdateDependencies }; ExecuteAsyncRequest asyncRequest = new ExecuteAsyncRequest() { Request = importSolutionRequest }; ExecuteAsyncResponse asyncResponse = this.CrmOrganization.Execute <ExecuteAsyncResponse>(asyncRequest); this.AsyncJobId = asyncResponse.AsyncJobId; DateTime end = DateTime.Now.AddSeconds(10); while (end >= DateTime.Now) { Entity asyncOperation = this.CrmOrganization.Retrieve("asyncoperation", this.AsyncJobId, new ColumnSet("asyncoperationid", "statuscode", "message")); switch (asyncOperation.GetAttributeValue <OptionSetValue>("statuscode").Value) { // 30: Succeeded // 0: Ready case 0: case 30: break; // 21: Pausing // 22: Canceling // 31: Failed // 32: Canceled case 21: case 22: case 31: case 32: throw new Exception(string.Format("Solution Import Failed: {0} {1}", asyncOperation["statuscode"], asyncOperation["message"])); default: break; } } } catch (FaultException <OrganizationServiceFault> ex) { if (ex.Detail.ErrorCode == CrmErrorCodes.ImportSolutionError) { // Todo: Log this to a file. CreateImportStatus(this.CrmOrganization.GetEntityByField("importjob", "importjobid", this.ImportJobId)); } throw; } ImportSolutionProgress(this.ImportJobId); job = this.CrmOrganization.GetEntityByField("importjob", "importjobid", this.ImportJobId); ImportSolutionResult status = CreateImportStatus(job); Logger.Log($"Solution {this.FileName} was imported with status {status.Status.ToString()}", LogLevel.Info); return(status); }
private static bool ImportSolution(ExportedSolution solution, IEnhancedOrgService service) { solution.Require(nameof(solution)); service.Require(nameof(service)); var importJobId = Guid.NewGuid(); var request = new ExecuteAsyncRequest { Request = new ImportSolutionRequest { CustomizationFile = solution.Data, ConvertToManaged = solution.IsManaged, OverwriteUnmanagedCustomizations = false, PublishWorkflows = true, SkipProductUpdateDependencies = true, ImportJobId = importJobId } }; log.Log($"Importing solution '{solution.SolutionName}' ..."); service.Execute(request); MonitorJobProgress(service, importJobId); var job = service.Retrieve("importjob", importJobId, new ColumnSet(ImportJob.Fields.Progress, ImportJob.Fields.Data)) .ToEntity <ImportJob>(); var importXmlLog = job.GetAttributeValue <string>("data"); if (importXmlLog.IsNotEmpty()) { var isFailed = ProcessErrorXml(importXmlLog); if (isFailed) { return(false); } } log.Log($"Imported!"); log.Log("Publishing customisations ..."); for (var i = 0; i < 3; i++) { Thread.Sleep(5000); try { service.Execute(new PublishAllXmlRequest()); log.Log("Finished publishing customisations."); break; } catch (Exception e) { log.Log(e); if (i < 2) { log.LogWarning("Retrying publish ..."); } } } return(true); }