Monday, May 23, 2016

Import/Export and Publish CRM Solutions programmatically in CRM 2015

 IMport/Export and Publish CRM Solutions programmatically



  private static void ExportCRMSolutions(bool managed = false)
        {

            if (ConfigurationHelper.CrmSolutions.Count() > 0)
            {
                Console.WriteLine(string.Format("{0} Exporting {1} Solution(s)", MESSAGE_PREFIX, ConfigurationHelper.CrmSolutions.Count().ToString()));

                foreach (string solution in ConfigurationHelper.CrmSolutions)
                {
                    // Retrieve version number for file name
                    QueryExpression querySolution = new QueryExpression
                    {
                        EntityName = "solution",
                        ColumnSet = new ColumnSet(new string[] { "version", "versionnumber" }),
                        Criteria = new FilterExpression()
                    };

                    querySolution.Criteria.AddCondition("uniquename", ConditionOperator.Equal, solution);
                    EntityCollection matchingSolutions = ServiceProxy_Origin.RetrieveMultiple(querySolution);

                    string version = matchingSolutions.Entities[0].Attributes["version"].ToString();
                    version = version.Replace('.', '_');

                    // Set Exported solution file name
                    string filename;
                    if (managed)
                    {
                        filename = solution + "_" + version + "_managed.zip";
                    }
                    else
                    {
                        filename = solution + "_" + version + ".zip";
                    }

                    if (managed)
                        Console.WriteLine(string.Format("{0} Exporting Managed Solution '{1}' from CRM Organization {2}", MESSAGE_PREFIX, solution, ConfigurationHelper.CrmSourceOrganization));
                    else
                        Console.WriteLine(string.Format("{0} Exporting Unmanaged Solution '{1}' from CRM Organization {2}", MESSAGE_PREFIX, solution, ConfigurationHelper.CrmSourceOrganization));

                    // Export Solution Request
                    ExportSolutionRequest exportRequest = new ExportSolutionRequest
                    {
                        Managed = managed,
                        SolutionName = solution
                    };
                    ExportSolutionResponse exportResponse = ServiceProxy_Origin.Execute(exportRequest) as ExportSolutionResponse;

                    // Write to disk
                    File.WriteAllBytes(ConfigurationHelper.CrmSolutionsDirectory + filename, exportResponse.ExportSolutionFile);

                    Console.WriteLine(string.Format("{0} Solution '{1}' Saved to disk as '{2}'", MESSAGE_PREFIX, solution, filename));
                }
            }
        }

        /// <summary>
        /// Import CRM solutions in target organization
        /// Note : uses the most recently modified UMANAGED solution in the target folder
        /// (no solution number comparison and no import of managed solutions either)
        /// </summary>
        /// <param name="publishAfterImport"></param>
        private static void ImportCRMSolutions(bool publishAfterImport = false)
        {
            if (ConfigurationHelper.CrmSolutions.Count() > 0)
            {
                Console.WriteLine(string.Format("{0} Importing {1} Solution(s)", MESSAGE_PREFIX, ConfigurationHelper.CrmSolutions.Count().ToString()));

                List<string> solutionFilesToImport = new List<string>();

                foreach (string solution in ConfigurationHelper.CrmSolutions)
                {
                    // get list of filenames matching our solution name
                    string[] dirs = Directory.GetFiles(ConfigurationHelper.CrmSolutionsDirectory, solution + "_*.zip");
                    SortedSet<FilenameDate> possibleCandidates = new SortedSet<FilenameDate>(new byDate());
                    foreach (string f in dirs)
                    { // retrieve their modified dates and sort by these
                        FileInfo d = new FileInfo(f);
                        possibleCandidates.Add(new FilenameDate { filename = f, modifiedDate = d.LastWriteTime });
                    }
                    IEnumerator<FilenameDate> candidates = possibleCandidates.Reverse().GetEnumerator();
                    while (candidates.MoveNext() != false)
                    {   // take the newest file, excluding managed solutions
                        if (!candidates.Current.filename.Contains("managed.zip"))
                        {
                            solutionFilesToImport.Add(candidates.Current.filename);
                            break;
                        }
                    }
                }

                foreach (string file in solutionFilesToImport)
                {
                    Console.WriteLine(string.Format("{0} Importing Solution at '{1}' to CRM Organization {2}", MESSAGE_PREFIX, file, ConfigurationHelper.CrmTargetOrganization));

                    ImportSolutionRequest importSolution = new ImportSolutionRequest
                    {
                        OverwriteUnmanagedCustomizations = true,
                        CustomizationFile = File.ReadAllBytes(file),
                        PublishWorkflows = true,
                        ImportJobId = Guid.NewGuid()
                    };

                    try
                    {
                        ImportSolutionResponse importResponse = ServiceProxy_Target.Execute(importSolution) as ImportSolutionResponse;
                    }
                    catch (Exception e)
                    {
                        if (!e.Message.StartsWith("The request channel timed out while waiting for a reply after "))
                        {
                            throw e; // if timed out, ignore exception, otherwise throw
                        }
                    }

                    String SolutionImportResult = null;
                    String PercentDone = null;
                    double percent = 0.0;
                    do
                    {

                        try
                        {
                            Entity job = ServiceProxy_Target.Retrieve("importjob", importSolution.ImportJobId, new
                            ColumnSet(new System.String[] { "data", "solutionname" }));

                            System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
                            doc.LoadXml(job["data"].ToString());
                            PercentDone = doc.SelectSingleNode("importexportxml/@progress").Value;
                            SolutionImportResult = doc.SelectSingleNode("//solutionManifest/result/@result").Value;
                            percent = Double.Parse(PercentDone);
                        }
                        catch (Exception e)
                        {
                            Console.WriteLine(e.Message);
                        }

                        if (percent < 100)
                        {
                            Console.WriteLine("    Import is {0}% complete.", percent);
                            System.Threading.Thread.Sleep(10000);
                        }

                    } while (percent < 100 && SolutionImportResult.CompareTo("success") == 0);

                    Console.WriteLine("{0} Solution Import Result: {1}", MESSAGE_PREFIX, SolutionImportResult.ToUpper());
                }

                if (publishAfterImport)
                    PublishAllCustomizations();
            }
        }

        /// <summary>
        /// Publish all customizations in Target environment
        /// </summary>
        /// <returns></returns>
        private static PublishAllXmlResponse PublishAllCustomizations()
        {
            PublishAllXmlResponse response = null;
            PublishAllXmlRequest req = new PublishAllXmlRequest();
            req.RequestId = Guid.NewGuid();

            Console.WriteLine(string.Format("{0} Publishing all customizations for organization {1}. Please wait...", MESSAGE_PREFIX, ConfigurationHelper.CrmTargetOrganization));
            try
            {
                response = ServiceProxy_Target.Execute(req) as PublishAllXmlResponse;
            }
            catch (Exception e)
            {
                if (!e.Message.StartsWith("The request channel timed out while waiting for a reply after "))
                {
                    throw e; // if timed out, ignore exception
                }
                else
                {
                    Console.WriteLine("Publishing all customizations has not yet completed (the service request timed out).");
                }
            }

            Console.WriteLine(string.Format("{0} Publishing all customizations *** Success ***", MESSAGE_PREFIX));

            return response;
        }



2 comments:

  1. I really liked this part of the article, with a nice and interesting topics have helped a lot of people who do not challenge things people should know... you need more publicize this so many people who know about it are rare for people to know this......
    CRM Software in India
    CRM Software in Chennai

    ReplyDelete
  2. Anyone knows if there is a connection between the "success" result and the "progress"? We have a powershell script which has a statement with
    ($importJobResult -eq "success" -and [int]$importJobProgress -lt 100)

    Fact is that we have a solution which says "success" and has a progress of "99.25". Importing manually works fine, but this part of the script fails obiously. Is success the best indicator to check and why is the progress not at "100".

    If anyone knows?

    ReplyDelete