Tuesday, October 20, 2009

Backup, Restore & Publish Dynamics CRM Customizations Programmatically

Thanks to gperera in giving out this wonderful class.

Find the excerpts..

Here is a simple class you can use to backup, restore and publish dynamics crm customizations programmatically. Please keep in mind that dynamics crm customizations are additive, which means, if you import a set of customizations lets say a new attribute on the account entity and you restore a backup of the old customizations the new attribute on the account entity that was imported will not be deleted.

CrmCustomizations customizations = new CrmCustomizations(service);

You can backup to an xml file or a zip file by calling the Backup method. Backup method takes care of creating the xml or zip file by looking at the output file extension.

bool backedup = customizations.Backup(@".\customizations_backup.xml");

 or to a zip file

backedup = customizations.Backup(@".\customizations_backup.zip");

To restore a backup call the Restore method. You can pass it a .zip file //or a .xml file path.

bool restored = customizations.Restore(@".\customizations.xml");

Once you have restored you need to publish the customizations, to publish call the Publish method. It will publish all customizations.

bool published = customizations.Publish();

Find the class file below :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Crm.SdkTypeProxy;
using System.IO;
using System.IO.Compression;

public class CrmCustomizations
{
private CrmService _service = null;
public CrmCustomizations(CrmService service)
{
_service = service;
}

public bool Backup(string filePath)
{
bool backedup = false;

if (_service != null)
{
// grab all the customizations first
ExportAllXmlRequest request = new ExportAllXmlRequest();
ExportAllXmlResponse response = _service.Execute(request) as ExportAllXmlResponse;

byte[] data = Encoding.ASCII.GetBytes(response.ExportXml);

// prepare the backup file
if (File.Exists(filePath)) { File.Delete(filePath); }
FileStream fs = File.Create(filePath);

// check if we need to create a zip file
bool createZip = Path.GetExtension(filePath).ToLower().Equals(".zip");
if (createZip)
{
GZipStream gzs = new GZipStream(fs, CompressionMode.Compress, true);
gzs.Write(data, 0, data.Length);
gzs.Close();
}
else
{
fs.Write(data, 0, data.Length);
}
fs.Close();

backedup = true;
}

return backedup;
}

public bool Restore(string filePath)
{
bool restored = false;

if (_service != null && File.Exists(filePath))
{
string customizationXml = ReadData(filePath);
if (!string.IsNullOrEmpty(customizationXml))
{
ImportAllXmlRequest request = new ImportAllXmlRequest { CustomizationXml = customizationXml };
//_service.Execute(request);

restored = true;
}
}

return restored;
}

public bool Publish()
{
bool published = false;

if (_service != null)
{
PublishAllXmlRequest request = new PublishAllXmlRequest();
_service.Execute(request);

published = true;
}

return published;
}

private string ReadData(string filePath)
{
FileStream fs = File.Open(filePath, FileMode.Open);
byte[] data = new byte[fs.Length];

bool isZip = Path.GetExtension(filePath).ToLower().Equals(".zip");
if (isZip)
{
GZipStream gzs = new GZipStream(fs, CompressionMode.Decompress, true);
// decompress
MemoryStream stream = new MemoryStream();
byte[] b = new byte[4096];
while (true)
{
int n = gzs.Read(b, 0, b.Length);
if (n > 0) { stream.Write(b, 0, n); }
else { break; }
}

data = stream.ToArray();

stream.Close();
gzs.Close();
}
else
{
fs.Read(data, 0, data.Length);
}

fs.Close();

return Encoding.ASCII.GetString(data);
}
}

Happy coding...

Labels: , , , , , , , , , ,

Friday, October 2, 2009

'The application is already precompiled' error

Iam not sure about the cause for the eror "The application is already precompiled". I faced this error while publishing the website.


The workaround for this error is to delete the 'PrecompiledApp.config' file (also not sure how it is created in the website directory) in your website directory.

Labels: , , , , , , ,