Example #1
0
        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();
        }
Example #2
0
        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);
        }
Example #3
0
        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));
        }
Example #5
0
        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));
        }
Example #7
0
        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);
        }
Example #8
0
        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();
                }
            }
        }
Example #9
0
        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);
        }
Example #10
0
        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);
        }
Example #11
0
        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
            });
        }
Example #12
0
        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);
        }
Example #15
0
        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);
        }
Example #17
0
        /// <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();
        }
Example #18
0
        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");
        }
Example #20
0
        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 + "\"");
                    }
                }
            }
        }
Example #21
0
        /// <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);
            }
        }
Example #22
0
        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));
            }
        }
Example #23
0
        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);
        }
Example #26
0
        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);
        }