Example #1
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 #2
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 #3
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 #4
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 #5
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));
            }
        }
        /// <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 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);
        }