The deployment of components from the lower environment to the higher environment is always an important aspect in any project implementation, and for products like Dynamics CRM wherein we have a solution containing all the required components, packing and unpacking is an important step for keeping track of changes that have been deployed over the target environments.

Solution packager plays an important role in unpacking/packing solutions that have been deployed for Dynamics CRM, and it’s part of the tool suite offered by Microsoft.

Sample Command for Solution Packager

SolutionPackager.exe /action:Pack: Extract /zip file: "Folder Path" /folder: "Folder Path" /map: "Mapping File Path"

To extract components from solutions exported out from Dynamics CRM, an individual has to pass a specific set of parameters

Importance of Map.XML

Scenario

Screenshot of Sample Map.XML file

Screenshot of Sample Project in Visual Studio

Steps for Programmatically Creating the Mapping File

Explanation to code

Screenshot for sample code

Program. cs -- Class

public static void Main(string[] args)
{
    string DirectoryPath = @"C:\Sumit\Work\WebResources\Scripts";
    string updatedPath = "..\\..";

    string finalPath = string.Empty;
    string mappingFilePath = string.Empty;

    string solutionDirectoryPath = @"C:\Sumit\Work\CRM Solutions\Demo\WebResources";
    string[] solutionFilePaths = Directory.GetFiles(solutionDirectoryPath, "*.*", SearchOption.AllDirectories);
    string solutionFinalPath = string.Empty;
    string mappingSolutionFilePath = string.Empty;
    string sourceFilePath = string.Empty;

    try
    {
        for (int i = 0; i < solutionFilePaths.Length; i++)
        {
            solutionFinalPath = solutionFilePaths[i];
            int filePathLength = solutionFinalPath.Length;

            if (!solutionFinalPath.Contains("data.xml"))
            {
                sourceFilePath = solutionFinalPath;
                int fileFormatPosition = 0;
                if (sourceFilePath.Contains('.'))
                {
                    fileFormatPosition = sourceFilePath.LastIndexOf(".");
                    sourceFilePath = sourceFilePath.Substring(0, ((fileFormatPosition)));
                }

                int startIndexWebResource = sourceFilePath.IndexOf("WebResources");
                sourceFilePath = sourceFilePath.Substring(((startIndexWebResource)));

                Logger.Write(string.Format("{0}{1}{2}", "<FileToFile map=\"", sourceFilePath, "\""));

                int charPosition = solutionFinalPath.LastIndexOf("\\");
                string fileName = solutionFinalPath.Substring(charPosition + 1, (filePathLength - (charPosition + 1)));

                string[] filePaths = Directory.GetFiles(DirectoryPath, string.Format("{0}.*", fileName), SearchOption.AllDirectories);
                for (int j = 0; j < filePaths.Length; j++)
                {
                    finalPath = filePaths[j].Replace(DirectoryPath, updatedPath);
                    mappingFilePath = String.Format("   to=\"{0}{1}", finalPath, "\" />");
                    Logger.WriteLine(mappingFilePath);
                }
            }
        }

        Logger.SaveLog(true);
    }
    catch (Exception ex)
    {
        Logger.WriteLine("Cannot open TextFile.txt for writing");
    }
}

Logger. cs Class

public static void SaveLog(bool Append = false, string Path = @"C:\Sumit\Work\C\Map.txt")
{
    if (LogString != null && LogString.Length > 0)
    {
        if (Append)
        {
            using (StreamWriter file = System.IO.File.AppendText(Path))
            {
                file.Write(LogString.ToString());
                file.Close();
                file.Dispose();
            }
        }
        else
        {
            using (System.IO.StreamWriter file = new System.IO.StreamWriter(Path))
            {
                file.Write(LogString.ToString());
                file.Close();
                file.Dispose();
            }
        }
    }
}

Screenshot for sample mapping file generated by an application.

<FileToFile map="WebResources\sumit_Account_OnLoad" to="..\..\sumit_Account_OnLoad.js" />
<FileToFile map="WebResources\demo_\index" to="..\..\demo\index.html" />