So I'm registering a nice, new workflow assembly to Disk in CRM 2011 (so I can debug a workflow for a colleague).
Having loaded the assembly itself, the CRM Plugin Registration Tool give me the following (unhelpful) error:
Assembly can not be loaded. (Error Code -2147200995)
Now there isn't much help on the Interwebs on this error number, so I had to resort to the CRM Trace Log. The trace log was equally unhelpful (I've included it here for reference):
[2014-01-29 09:46:16.411] Process: w3wp |Organization:782510f2-4d72-e211-bd58-001e6837aeb7 |Thread: 25 |Category: Platform.Sql |User: 85e569d9-f7d6-e211-8851-00155d0a8940 |Level: Info |ReqId: 11a1058c-12c8-4ef4-9007-ea5bf87fba64 | BusinessProcessObject.ExecuteQuery ilOffset = 0x3E
>select
"plugintype0".TypeName as "typename"
, "plugintype0".IsWorkflowActivity as "isworkflowactivity"
, "plugintype0".PluginTypeId as "plugintypeid"
from
PluginType as "plugintype0"
where
(("plugintype0".PluginAssemblyId = 'f3c498c4-f911-4a9a-a3da-c741be957d08'))
[2014-01-29 09:46:16.411] Process: w3wp |Organization:782510f2-4d72-e211-bd58-001e6837aeb7 |Thread: 25 |Category: Platform.Sql |User: 85e569d9-f7d6-e211-8851-00155d0a8940 |Level: Verbose |ReqId: 11a1058c-12c8-4ef4-9007-ea5bf87fba64 | CrmDbConnection.InternalExecuteReader ilOffset = 0x16
>select
"plugintype0".TypeName as "typename"
, "plugintype0".IsWorkflowActivity as "isworkflowactivity"
, "plugintype0".PluginTypeId as "plugintypeid"
from
PluginType as "plugintype0"
where
(("plugintype0".PluginAssemblyId = 'f3c498c4-f911-4a9a-a3da-c741be957d08'))
[2014-01-29 09:46:16.411] Process: w3wp |Organization:782510f2-4d72-e211-bd58-001e6837aeb7 |Thread: 25 |Category: Platform.Sql |User: 85e569d9-f7d6-e211-8851-00155d0a8940 |Level: Verbose |ReqId: 11a1058c-12c8-4ef4-9007-ea5bf87fba64 | CrmDbConnection.InternalExecuteReader ilOffset = 0xDD
>Query execution time: 0.0 seconds; database: CRMORG_MSCRM; Server:SQLSERVER; command: select
"plugintype0".TypeName as "typename"
, "plugintype0".IsWorkflowActivity as "isworkflowactivity"
, "plugintype0".PluginTypeId as "plugintypeid"
from
PluginType as "plugintype0"
where
(("plugintype0".PluginAssemblyId = 'f3c498c4-f911-4a9a-a3da-c741be957d08')).
[2014-01-29 09:46:16.489] Process: w3wp |Organization:782510f2-4d72-e211-bd58-001e6837aeb7 |Thread: 25 |Category: Exception |User: 85e569d9-f7d6-e211-8851-00155d0a8940 |Level: Error |ReqId: 11a1058c-12c8-4ef4-9007-ea5bf87fba64 | CrmException..ctor ilOffset = 0x0
at CrmException..ctor(String message, Exception innerException, Int32 errorCode, Boolean isFlowControlException) ilOffset = 0x0
at CrmException..ctor(String message, Int32 errorCode) ilOffset = 0x0
at CustomActivityInfoMetadataBase.GetCustomActivityInfo(ActivityInfo activityInfo, Int32 isolationMode) ilOffset = 0x17A
at WorkflowSandboxCustomActivityValidator.ValidateInternal() ilOffset = 0x1EF
at PluginValidatorBase.Validate() ilOffset = 0x12
at PluginTypeValidator.ValidateInternal() ilOffset = 0xCE
at PluginValidatorBase.Validate() ilOffset = 0x12
at AssemblyDataCanBeUpdatedValidator.ValidateInternal() ilOffset = 0x261
at PluginAssemblyServiceInternal`1.VerifyRegistrationAbility(IBusinessEntity pluginAssembly, Boolean createCall, ExecutionContext context) ilOffset = 0x8E
at SdkEntityServiceBase.UpdateInternal(IBusinessEntity entity, ExecutionContext context, Boolean verifyAction) ilOffset = 0x10
at PluginAssemblyServiceInternal`1.Update(IBusinessEntity entity, ExecutionContext context) ilOffset = 0x4A
at RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor) ilOffset = 0xFFFFFFFF
at RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments) ilOffset = 0x25
at RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) ilOffset = 0x84
at LogicalMethodInfo.Invoke(Object target, Object[] values) ilOffset = 0x4F
at InternalOperationPlugin.Execute(IServiceProvider serviceProvider) ilOffset = 0x57
at V5PluginProxyStep.ExecuteInternal(PipelineExecutionContext context) ilOffset = 0x58
at VersionedPluginProxyStepBase.Execute(PipelineExecutionContext context) ilOffset = 0x65
at Pipeline.Execute(PipelineExecutionContext context) ilOffset = 0x65
at MessageProcessor.Execute(PipelineExecutionContext context) ilOffset = 0x1C5
at InternalMessageDispatcher.Execute(PipelineExecutionContext context) ilOffset = 0xE4
at ExternalMessageDispatcher.ExecuteInternal(IInProcessOrganizationServiceFactory serviceFactory, IPlatformMessageDispatcherFactory dispatcherFactory, String messageName, String requestName, Int32 primaryObjectTypeCode, Int32 secondaryObjectTypeCode, ParameterCollection fields, CorrelationToken correlationToken, CallerOriginToken originToken, UserAuth userAuth, Guid callerId, Guid transactionContextId, Int32 invocationSource, Nullable`1 requestId, Version endpointVersion) ilOffset = 0x156
at OrganizationSdkServiceInternal.ExecuteRequest(OrganizationRequest request, CorrelationToken correlationToken, CallerOriginToken callerOriginToken, WebServiceType serviceType, UserAuth userAuth, Guid targetUserId, Boolean traceRequest, OrganizationContext context, Boolean returnResponse) ilOffset = 0x145
at OrganizationSdkServiceInternal.ExecuteRequest(OrganizationRequest request, CorrelationToken correlationToken, CallerOriginToken callerOriginToken, WebServiceType serviceType) ilOffset = 0x34
at OrganizationSdkServiceInternal.Update(Entity entity, CorrelationToken correlationToken, CallerOriginToken callerOriginToken, WebServiceType serviceType) ilOffset = 0x2D
at ilOffset = 0xFFFFFFFF
at SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs) ilOffset = 0x241
at DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc) ilOffset = 0x100
at ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc) ilOffset = 0x48
at ImmutableDispatchRuntime.ProcessMessage31(MessageRpc& rpc) ilOffset = 0xC6
at MessageRpc.Process(Boolean isOperationContextSet) ilOffset = 0x62
at ChannelHandler.DispatchAndReleasePump(RequestContext request, Boolean cleanThread, OperationContext currentOperationContext) ilOffset = 0x256
at ChannelHandler.HandleRequest(RequestContext request, OperationContext currentOperationContext) ilOffset = 0xF1
at ChannelHandler.AsyncMessagePump(IAsyncResult result) ilOffset = 0x39
at AsyncThunk.UnhandledExceptionFrame(IAsyncResult result) ilOffset = 0x0
at AsyncResult.Complete(Boolean completedSynchronously) ilOffset = 0xC2
at ReceiveItemAndVerifySecurityAsyncResult`2.InnerTryReceiveCompletedCallback(IAsyncResult result) ilOffset = 0x55
at AsyncThunk.UnhandledExceptionFrame(IAsyncResult result) ilOffset = 0x0
at AsyncResult.Complete(Boolean completedSynchronously) ilOffset = 0xC2
at AsyncQueueReader.Set(Item item) ilOffset = 0x21
at InputQueue`1.Dispatch() ilOffset = 0x121
at ScheduledOverlapped.IOCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped) ilOffset = 0x22
at IOCompletionThunk.UnhandledExceptionFrame(UInt32 error, UInt32 bytesRead, NativeOverlapped* nativeOverlapped) ilOffset = 0x5
at _IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP) ilOffset = 0x3C
>Crm Exception: Message: Assembly can not be loaded., ErrorCode: -2147200995
[2014-01-29 09:46:16.489] Process: w3wp |Organization:00000000-0000-0000-0000-000000000000 |Thread: 25 |Category: Platform |User: 85e569d9-f7d6-e211-8851-00155d0a8940 |Level: Info |ReqId: 11a1058c-12c8-4ef4-9007-ea5bf87fba64 | ExceptionConverter.IsSandboxException ilOffset = 0x3F
>IsSandboxException: TargetInvocationException
[2014-01-29 09:46:16.489] Process: w3wp |Organization:00000000-0000-0000-0000-000000000000 |Thread: 25 |Category: Platform |User: 85e569d9-f7d6-e211-8851-00155d0a8940 |Level: Info |ReqId: 11a1058c-12c8-4ef4-9007-ea5bf87fba64 | ExceptionConverter.IsSandboxException ilOffset = 0x8B
>IsSandboxException: false
[2014-01-29 09:46:16.505] Process: w3wp |Organization:782510f2-4d72-e211-bd58-001e6837aeb7 |Thread: 25 |Category: Platform.Sdk |User: 85e569d9-f7d6-e211-8851-00155d0a8940 |Level: Error |ReqId: 11a1058c-12c8-4ef4-9007-ea5bf87fba64 | VersionedPluginProxyStepBase.Execute ilOffset = 0x65
>Web Service Plug-in failed in SdkMessageProcessingStepId: {A0CDBB1B-EA3E-DB11-86A7-000A3A5473E8}; EntityName: pluginassembly; Stage: 30; MessageName: Update; AssemblyName: Microsoft.Crm.Extensibility.InternalOperationPlugin, Microsoft.Crm.ObjectModel, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35; ClassName: Microsoft.Crm.Extensibility.InternalOperationPlugin; Exception: Unhandled Exception: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation.
at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Web.Services.Protocols.LogicalMethodInfo.Invoke(Object target, Object[] values)
at Microsoft.Crm.Extensibility.InternalOperationPlugin.Execute(IServiceProvider serviceProvider)
at Microsoft.Crm.Extensibility.V5PluginProxyStep.ExecuteInternal(PipelineExecutionContext context)
at Microsoft.Crm.Extensibility.VersionedPluginProxyStepBase.Execute(PipelineExecutionContext context)
Inner Exception: Microsoft.Crm.CrmException: Assembly can not be loaded.
at Microsoft.Crm.Workflow.ObjectModel.CustomActivityInfoMetadataBase.GetCustomActivityInfo(ActivityInfo activityInfo, Int32 isolationMode)
at Microsoft.Crm.ObjectModel.WorkflowSandboxCustomActivityValidator.ValidateInternal()
at Microsoft.Crm.ObjectModel.PluginValidatorBase.Validate()
at Microsoft.Crm.ObjectModel.PluginTypeValidator.ValidateInternal()
at Microsoft.Crm.ObjectModel.PluginValidatorBase.Validate()
at Microsoft.Crm.ObjectModel.AssemblyDataCanBeUpdatedValidator.ValidateInternal()
at Microsoft.Crm.ObjectModel.PluginAssemblyServiceInternal`1.VerifyRegistrationAbility(IBusinessEntity pluginAssembly, Boolean createCall, ExecutionContext context)
at Microsoft.Crm.ObjectModel.SdkEntityServiceBase.UpdateInternal(IBusinessEntity entity, ExecutionContext context, Boolean verifyAction)
at Microsoft.Crm.ObjectModel.PluginAssemblyServiceInternal`1.Update(IBusinessEntity entity, ExecutionContext context)
.
[2014-01-29 09:46:16.505] Process: w3wp |Organization:782510f2-4d72-e211-bd58-001e6837aeb7 |Thread: 25 |Category: Exception |User: 85e569d9-f7d6-e211-8851-00155d0a8940 |Level: Error |ReqId: 11a1058c-12c8-4ef4-9007-ea5bf87fba64 | CrmException..ctor ilOffset = 0x0
at CrmException..ctor(String message, Exception innerException, Int32 errorCode, Boolean isFlowControlException) ilOffset = 0x0
at CrmException..ctor(String message, Exception innerException, Int32 errorCode) ilOffset = 0x0
at RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor) ilOffset = 0xFFFFFFFF
at RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) ilOffset = 0xF7
at RuntimeType.CreateInstanceImpl(BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes, StackCrawlMark& stackMark) ilOffset = 0x1E8
at Activator.CreateInstance(Type type, BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes) ilOffset = 0xB1
at Activator.CreateInstance(Type type, Object[] args) ilOffset = 0x0
at VersionedPluginProxyStepBase.WrapExceptionToThrow(CrmException exception) ilOffset = 0xA5
at VersionedPluginProxyStepBase.Execute(PipelineExecutionContext context) ilOffset = 0x65
at Pipeline.Execute(PipelineExecutionContext context) ilOffset = 0x65
at MessageProcessor.Execute(PipelineExecutionContext context) ilOffset = 0x1C5
at InternalMessageDispatcher.Execute(PipelineExecutionContext context) ilOffset = 0xE4
at ExternalMessageDispatcher.ExecuteInternal(IInProcessOrganizationServiceFactory serviceFactory, IPlatformMessageDispatcherFactory dispatcherFactory, String messageName, String requestName, Int32 primaryObjectTypeCode, Int32 secondaryObjectTypeCode, ParameterCollection fields, CorrelationToken correlationToken, CallerOriginToken originToken, UserAuth userAuth, Guid callerId, Guid transactionContextId, Int32 invocationSource, Nullable`1 requestId, Version endpointVersion) ilOffset = 0x156
at OrganizationSdkServiceInternal.ExecuteRequest(OrganizationRequest request, CorrelationToken correlationToken, CallerOriginToken callerOriginToken, WebServiceType serviceType, UserAuth userAuth, Guid targetUserId, Boolean traceRequest, OrganizationContext context, Boolean returnResponse) ilOffset = 0x145
at OrganizationSdkServiceInternal.ExecuteRequest(OrganizationRequest request, CorrelationToken correlationToken, CallerOriginToken callerOriginToken, WebServiceType serviceType) ilOffset = 0x34
at OrganizationSdkServiceInternal.Update(Entity entity, CorrelationToken correlationToken, CallerOriginToken callerOriginToken, WebServiceType serviceType) ilOffset = 0x2D
at ilOffset = 0xFFFFFFFF
at SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs) ilOffset = 0x241
at DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc) ilOffset = 0x100
at ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc) ilOffset = 0x48
at ImmutableDispatchRuntime.ProcessMessage31(MessageRpc& rpc) ilOffset = 0xC6
at MessageRpc.Process(Boolean isOperationContextSet) ilOffset = 0x62
at ChannelHandler.DispatchAndReleasePump(RequestContext request, Boolean cleanThread, OperationContext currentOperationContext) ilOffset = 0x256
at ChannelHandler.HandleRequest(RequestContext request, OperationContext currentOperationContext) ilOffset = 0xF1
at ChannelHandler.AsyncMessagePump(IAsyncResult result) ilOffset = 0x39
at AsyncThunk.UnhandledExceptionFrame(IAsyncResult result) ilOffset = 0x0
at AsyncResult.Complete(Boolean completedSynchronously) ilOffset = 0xC2
at ReceiveItemAndVerifySecurityAsyncResult`2.InnerTryReceiveCompletedCallback(IAsyncResult result) ilOffset = 0x55
at AsyncThunk.UnhandledExceptionFrame(IAsyncResult result) ilOffset = 0x0
at AsyncResult.Complete(Boolean completedSynchronously) ilOffset = 0xC2
at AsyncQueueReader.Set(Item item) ilOffset = 0x21
at InputQueue`1.Dispatch() ilOffset = 0x121
at ScheduledOverlapped.IOCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped) ilOffset = 0x22
at IOCompletionThunk.UnhandledExceptionFrame(UInt32 error, UInt32 bytesRead, NativeOverlapped* nativeOverlapped) ilOffset = 0x5
at _IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP) ilOffset = 0x3C
>Crm Exception: Message: Assembly can not be loaded., ErrorCode: -2147200995, InnerException: Microsoft.Crm.CrmException: Assembly can not be loaded.
at Microsoft.Crm.Workflow.ObjectModel.CustomActivityInfoMetadataBase.GetCustomActivityInfo(ActivityInfo activityInfo, Int32 isolationMode)
at Microsoft.Crm.ObjectModel.WorkflowSandboxCustomActivityValidator.ValidateInternal()
at Microsoft.Crm.ObjectModel.PluginValidatorBase.Validate()
at Microsoft.Crm.ObjectModel.PluginTypeValidator.ValidateInternal()
at Microsoft.Crm.ObjectModel.PluginValidatorBase.Validate()
at Microsoft.Crm.ObjectModel.AssemblyDataCanBeUpdatedValidator.ValidateInternal()
at Microsoft.Crm.ObjectModel.PluginAssemblyServiceInternal`1.VerifyRegistrationAbility(IBusinessEntity pluginAssembly, Boolean createCall, ExecutionContext context)
at Microsoft.Crm.ObjectModel.SdkEntityServiceBase.UpdateInternal(IBusinessEntity entity, ExecutionContext context, Boolean verifyAction)
at Microsoft.Crm.ObjectModel.PluginAssemblyServiceInternal`1.Update(IBusinessEntity entity, ExecutionContext context)
So on the surface of it not entirely helpful, particularly when the assembly registers without issue to the database, just not to disk. All our plugin assemblies register correctly, just not our workflow assemblies.
Our combined thinking was that, perhaps, an older assembly reference was unable to be loaded. So here's what we did:
- Go through all the assemblies that referenced our workflow assembly (our Data, CRM Repository, and Business Logic are all abstracted away to other assemblies for later - more on this at another time) and make sure that these assemblies don't reference anything that they don't need to.
- We found an unused reference to Microsoft.Xrm.Client.dll that wasn't required in the CRM Repository assembly, so we removed that.
- Removed all references in %Program Files%\Microsoft Dynamics CRM\Server\bin\assembly other than the assemblies we were registering to ensure that the .
- Go through all the projects that referenced CRM assemblies, and ensure that they were referencing the same identical XRM assemblies, from the same location.. We were surprised how many projects and little plugins we had created from the XRM project wizard referenced XRM assemblies from a different location.
We then rebuilt and re-registered the offending assembly, and, hey presto! It worked. So a combination of the above improvements in best-practise (which seem obvious now, but require eternal vigilance) and keeping your dev house tidy, worked a treat.
As much as anything, it was another lesson in not just having clean code, but a clean implementation and a clean deployment too.
Now, if I can just convince all my clients onto the same CRM rollup, I'll be laughing!
Happy deploying everyone!