Hello everyone,
EDIT (06/14/2017) : A plugin was integrated into the famous XRMToolBox application, see at the end of the article for the details.
Today, i'm gonna talk about the probably most famous error of the Crm developpers when updating an assembly on your CRM :
Plug-in assembly does not contain the required types or assembly content cannot be updated.
I'm sure you all have struggled during a lot of hours to find out / remember what you've done between the assembly update this time and the previous one.
Unfortunately you also know that based on the error message provided by the Plugin Registration Tool (or what ever you use to update the assembly), you have not the correct information to spot the exact issue.
Today, after years of issues and waste of time, I decided to create a quick tool to find out what was the difference between your assembly on the CRM and the one you are trying to push, this was done in an hour maximum.
Here is a teasing of the final result :
To have this result, you have two "simple" things to do actually :
- Retrieve all classes on your dll assembly
- Retrieve all custom plugin names from your CRM
- Get a diff of the 2 lists and that's it !
Step 1 : retrieve the classes from your DLL
I decided to go for a quick solution here, I added the assembly dll to my project then in one line I retrieve the classes :
var localAssemblyClasses = Assembly.LoadWithPartialName("YourAssemblyName").GetTypes()
.Where(t => (t.FullName.Contains("Plugins"))
.Select(t => t.FullName).ToList();
This will return me the list of all classes included in my assembly having the word "Plugins" in the name. This allow me to filter only the classes I'm interested in.
Here is the result, I have on my system to give you an idea:
Step 2 : retrieve the plugins name from your CRM
A simple QueryExpression
with the proper criteria will do the job here :
CrmServiceClient crmSvc = new CrmServiceClient("Url=https://org.crm.dynamics.com; Username=username@email.onmicrosoft.com; Password=yourPassword;AuthType=Office365;");
IOrganizationService service = (IOrganizationService)crmSvc.OrganizationWebProxyClient != null ? (IOrganizationService)crmSvc.OrganizationWebProxyClient : (IOrganizationService)crmSvc.OrganizationServiceProxy;
QueryExpression queryExistingAssemblies = new QueryExpression()
{
EntityName = "plugintype",
ColumnSet = new ColumnSet(true)
};
queryExistingAssemblies.Criteria.AddCondition("assemblyname", ConditionOperator.Equal, "YourAssemblyName");
var crmlocalAssemblyClasses = service.RetrieveMultiple(queryExistingAssemblies).Entities
.Select(p => p.Attributes["typename"].ToString()).ToList();
Here is the result, I have on my system to give you an idea:
Step 3 : the comparaison of the 2 lists
The last step here is to compare the two lists we just retrieved from the above code.
var diffCrmLocal = crmlocalAssemblyClasses.Except(localAssemblyClasses).ToList();
var diffLocalCrm = localAssemblyClasses.Except(crmlocalAssemblyClasses).ToList();
And there you go !
In the "diffCrmLocal" variable, you will have the plugins which are present in the CRM but not in your local assembly (basically that what cause the issue usually for me)
In the "diffLocalCrm" variable, you will have the plugins which you just developed and are not in your CRM yet.
EDIT : Above was the theory explained. I thougt it would be a nice idea to integrate it into the XrmToolBox.
And this is now done ! You can find the package by the name :
Here is a quick screenshot to show you the result integration in the tool :
In basically, 5-6 clicks, you can now save hours. Sounds good to me !
I hope this will save you time :-).
Happy CRM'in,
Clément