Asynchronous Solution Import in Dynamics CRM 2013

One of the new features in the Dynamics CRM 2013 SDK is the ability to execute operations asynchronously. At the moment this feature is limited to only solution imports.

Previously in Dynamics CRM 2011 you were only able to import solutions synchronously. This means that the caller had to wait until the solution import process completes. This resulted in time out errors when importing large or complex solutions. Customers had to increase their time out settings significantly for on-premise deployments. For CRM online, the only option was to catch the exception and do some queries to figure out if the solution import was actually successful or no.

In Dynamics CRM 2013, the “ExecuteAsync” message solves this problem. All we have to do is submit a request to the Dynamics CRM Organization Service using this message. The message would kick off a server side process asynchronously to process the request and return the id of the server side process immediately to the caller. The caller then can query the status of the server side process to figure out if the request was processed correctly.

Take a look at the example below. This method supports both synchronous and asynchronous imports. For asynchronous imports, it can optionally wait for the import job to finish and report on the status.

Code Snippet
  1. public Guid? Import(string solutionFilePath,
  2.                     bool publishWorkflows,
  3.                     bool convertToManaged,
  4.                     bool overwriteUnmanagedCustomizations,
  5.                     bool importAsync,
  6.                     bool waitForCompletion,
  7.                     int sleepInterval,
  8.                     int asyncWaitTimeout)
  9. {
  10.     Guid? asyncJobId = null;
  11.     byte[] solutionBytes = File.ReadAllBytes(solutionFilePath);
  12.     ImportSolutionRequest importSolutionRequest = newImportSolutionRequest()
  13.     {
  14.         CustomizationFile = solutionBytes,
  15.         PublishWorkflows = publishWorkflows,
  16.         ConvertToManaged = convertToManaged,
  17.         OverwriteUnmanagedCustomizations = overwriteUnmanagedCustomizations
  18.     };
  19.     if (importAsync)
  20.     {
  21.         ExecuteAsyncRequest asyncRequest = newExecuteAsyncRequest()
  22.         {
  23.             Request = importSolutionRequest
  24.         };
  25.         ExecuteAsyncResponse asyncResponse = OrgService.Execute(asyncRequest) asExecuteAsyncResponse;
  26.         asyncJobId = asyncResponse.AsyncJobId;
  27.         if (waitForCompletion)
  28.         {
  29.             DateTime end = DateTime.Now.AddSeconds(asyncWaitTimeout);
  30.             while (end >= DateTime.Now)
  31.             {
  32.                 AsyncOperation asyncOperation = OrgService.Retrieve(“asyncoperation”, asyncJobId.Value,
  33.                     newColumnSet(“asyncoperationid”, “statuscode”, “message”)).ToEntity < AsyncOperation>();
  34.                 switch (asyncOperation.StatusCode.Value)
  35.                 {
  36.                     //Succeeded
  37.                     case 30:
  38.                         return asyncJobId;
  39.                     //Pausing //Canceling //Failed //Canceled
  40.                     case 21:
  41.                     case 22:
  42.                     case 31:
  43.                     case 32:
  44.                         thrownewException(string.Format(“Solution Import Failed: {0} {1}”,
  45.                             asyncOperation.StatusCode.Value, asyncOperation.Message));
  46.                     default:
  47.                         break;
  48.                 }
  49.             }
  50.             thrownewException(string.Format(“Import Timeout: {0}”, asyncWaitTimeout));
  51.         }
  52.         return asyncJobId;
  53.     }
  54.     else
  55.     {
  56.         ImportSolutionResponse importSolutionResponse = OrgService.Execute(importSolutionRequest) asImportSolutionResponse;
  57.     }
  58.     return asyncJobId;
  59. }

You can start using this feature immediately by downloading the xRM CI Toolkit. This will provide you with a PowerShell Cmdlet to do exactly the above. See an example on how to use this below. This script invokes the solution import asynchronously and waits until the import completes.

Code Snippet
  1. Import-Module “C:\Program Files (x86)\Xrm CI Framework\CRM 2013\PowerShell Cmdlets\Xrm.Framework.CI.PowerShell.dll”
  2. $connection = “ServiceUri=; Domain=XRM; UserName=Wael; Password=******”
  3. Import-XrmSolution -ConnectionString $connection -SolutionFilePath “C:\” -PublishWorkflows $true -ConvertToManaged $false -OverwriteUnmanagedCustomizations $true ImportAsync $true -WaitForCompletion $true

Check my previous post to learn more about the xRM CI Framework and how you can use it in your projects.


Posted on November 17, 2013, in CRM 2013, Dynamics CRM, xRM CI Framework and tagged , , . Bookmark the permalink. 8 Comments.

  1. Hi Wael. We’re timing out when importing a solution using ImportXrmSolution synchronously. But when we switch ImportAsync we get UnauthorizedAccessException errors. Any ideas? A Select-WhoAmI works fine so we can access CRM.

    Import-XrmSolution -ConnectionString $deployToConnectionString -SolutionFilePath $solutionPath -OverwriteUnmanagedCustomizations $true -ImportAsync $true -WaitForCompletion $true -AsyncWaitTimeout 600

  2. I also had the Access Denied problem. Unfortunately I read this comments just after I did the research by my self, wrote a Blog post about it and came back to post the link to save other peoples time.

  1. Pingback: xRM CI Framework for Dynamics CRM 2013 is now available | Wael Hamze

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: