Cmdlets/ExportSolution.cs

using Microsoft.Crm.Sdk.Messages;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
using Microsoft.Xrm.Tooling.Connector;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Management.Automation;
using System.Threading;
using Xrm.DevOps.Tools.Common;
 
namespace Xrm.DevOps.Tools.Cmdlets
{
    [Cmdlet(VerbsData.Export, "Solution")]
    public class ExportSolution : Cmdlet
    {
        [Parameter(Position = 1, Mandatory = true)]
        public string ConnectionString { get; set; }
 
        [Parameter(Position = 2, Mandatory = false)]
        public string SolutionName { get; set; }
 
        [Parameter(Position = 3, Mandatory = false)]
        public string FilePath { get; set; }
 
        [Parameter(Position = 4, Mandatory = true)]
        public string OutputPath { get; set; }
 
        private CrmServiceClient _client;
 
        protected override void BeginProcessing()
        {
            if (string.IsNullOrEmpty(FilePath) && string.IsNullOrEmpty(SolutionName))
            {
                ErrorRecord error = new ErrorRecord(new ArgumentNullException("Parameter SolutionName or FilePath must be provided."), "001", ErrorCategory.InvalidArgument, SolutionName);
                ThrowTerminatingError(error);
            }
 
            _client = new CrmServiceClient(ConnectionString);
        }
 
        protected override void ProcessRecord()
        {
            var solutions = GetSolutions();
 
            foreach (var solution in solutions)
            {
                ExportSolutionRequest request = new ExportSolutionRequest
                {
                    Managed = true,
                    SolutionName = solution,
                    RequestName = "ExportSolutionAsync"
                };
 
                var exportSolutionResponse = _client.Execute(request);
 
                Guid asyncJobId = (Guid)exportSolutionResponse.Results["AsyncOperationId"];
                Guid exportJobId = (Guid)exportSolutionResponse.Results["ExportJobId"];
 
                bool completed = false;
 
                while (!completed){
                     
                    // Default sleep time.
                    Thread.Sleep(10 * 1000);
 
                    Entity asyncOperation = _client.Retrieve("asyncoperation", asyncJobId, new ColumnSet("asyncoperationid", "statuscode", "message"));
 
                    if (asyncOperation.GetAttributeValue<OptionSetValue>("statuscode").Value == 30)
                    {
                        completed = true;
                    }
                }
 
                OrganizationRequest downloadReq = new OrganizationRequest("DownloadSolutionExportData");
                downloadReq.Parameters.Add("ExportJobId", exportJobId);
 
                OrganizationResponse downloadRes = _client.Execute(downloadReq);
 
                byte[] exportXml = (byte[])downloadRes.Results["ExportSolutionFile"];
                string filename = solution + ".zip";
 
                if (OutputPath.LastIndexOf('\\') == (OutputPath.Length - 1))
                {
                    File.WriteAllBytes($"{OutputPath}{filename}", exportXml);
                }
                else
                {
                    File.WriteAllBytes($"{OutputPath}\\{filename}", exportXml);
                }
            }
        }
 
        private List<string> GetSolutions()
        {
            var solutions = new List<string>();
 
            if (!string.IsNullOrEmpty(SolutionName))
            {
                WriteVerbose("Escolhido modo solution unica");
                solutions.Add(SolutionName);
            }
            else if (!string.IsNullOrEmpty(FilePath))
            {
                WriteVerbose("Escolhido modo arquivos");
                var fileContent = File.ReadAllText(FilePath);
 
                WriteVerbose($"Conteúdo do arquivo: {fileContent}");
 
                var json = JsonConvert.DeserializeObject<SolutionsJson>(fileContent);
 
                foreach (var solution in json.solutions)
                {
                    solutions.Add(solution);
                    WriteVerbose($"Solution {solution} adicionada");
                }
            }
            return solutions;
        }
 
        protected override void EndProcessing()
        {
 
        }
    }
}