title: ILMerge / ILRepack dlls fail to register with Dynamics 365 plugin registration tool
body: <p>I'm trying to create a plugin for D365.  I have package dependencies including</p>
  <ul>
  <li>Azure.DigitalTwins.Core</li>
  <li>Azure.Core</li>
  <li>Azure.Identity</li>
  </ul>
  <p>These .dll dependencies must be merged into a single .dll to register a plugin.  I'm using an <a href="https://github.com/dotnet/ILMerge#to-run-ilmerge-in-a-batch-file" rel="nofollow noreferrer">ILMerge</a> batch file script to combine these dlls into a single <code>merged.dll</code> output.</p>
  <p>Here's the script I'm using:</p>
  <pre><code>@echo off
  :: this script needs https://www.nuget.org/packages/ilmerge
  
  :: Set build, used for directory. Typically Release or Debug
  SET ILMERGE_BUILD=bin\Debug\ilmerge
  
  :: set your NuGet ILMerge Version, this is the number from the package manager install, for example:
  :: PM&gt; Install-Package ilmerge -Version 3.0.29
  :: to confirm it is installed for a given project, see the packages.config file
  SET ILMERGE_VERSION=3.0.41
  
  :: the full ILMerge should be found here:
  SET ILMERGE_PATH=%USERPROFILE%\.nuget\packages\ilmerge\%ILMERGE_VERSION%\tools\net452
  :: dir &quot;%ILMERGE_PATH%&quot;\ILMerge.exe
  
  SET PROJECT_ROOT=%CD%
  SET ASSEMBLY_DIR=%PROJECT_ROOT%\bin\Debug\net462
  
  ::/targetplatform:v4,&quot;C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0&quot; ^
  ::/target:library ^
  ::/copyattrs ^
  ::/closed ^
  ::/allowDup ^
  
  echo Merging adtplugin...
  :: add project DLL's starting with replacing the FirstLib with this project's DLL
  &quot;%ILMERGE_PATH%&quot;\ILMerge.exe ^
  /keyfile:%PROJECT_ROOT%\adtplugin.snk ^
  /out:%ILMERGE_BUILD%\merged.dll ^
  /target:library ^
  /nDebug ^
  /closed ^
  /allowDup ^
  /copyattrs ^
  /targetplatform:v4,&quot;C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.7.2&quot; ^
  %ASSEMBLY_DIR%\adtplugin.dll ^
  %ASSEMBLY_DIR%\Azure.Core.dll ^
  %ASSEMBLY_DIR%\Azure.DigitalTwins.Core.dll ^
  %ASSEMBLY_DIR%\Azure.Identity.dll ^
  %ASSEMBLY_DIR%\Microsoft.Bcl.AsyncInterfaces.dll ^
  %ASSEMBLY_DIR%\Microsoft.Identity.Client.dll ^
  %ASSEMBLY_DIR%\Microsoft.Identity.Client.Extensions.Msal.dll ^
  %ASSEMBLY_DIR%\Microsoft.Win32.Primitives.dll ^
  %ASSEMBLY_DIR%\netstandard.dll ^
  %ASSEMBLY_DIR%\System.Memory.dll ^
  %ASSEMBLY_DIR%\System.Threading.Tasks.Extensions.dll 
  
  pause
  :Done
  
  </code></pre>
  <p>I've played around quite a bit with the /option flags passed to ILMerge.exe. Currently with the config shown, I'm able to merge the .dlls listed into a single merged.dll output.</p>
  <p>Next, I'm trying to use the Plug-in registration tool to register a new assembly using the <code>merged.dll</code> output file.  When I try to register the plugin I'm getting errors:</p>
  <p><a href="https://i.stack.imgur.com/pxKfR.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/pxKfR.png" alt="Plug-in registration tool" /></a></p>
  <p>Here's the error dump:</p>
  <pre><code>Unhandled Exception: System.ServiceModel.FaultException`1[[Microsoft.Xrm.Sdk.OrganizationServiceFault, Microsoft.Xrm.Sdk, Version=9.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]: Unable to load plug-in assembly.
  Detail: &lt;OrganizationServiceFault xmlns=&quot;http://schemas.microsoft.com/xrm/2011/Contracts&quot; xmlns:i=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;&gt;
    &lt;ActivityId&gt;9e6ed737-8374-464e-956a-d70b46a2c686&lt;/ActivityId&gt;
    &lt;ErrorCode&gt;-2147204719&lt;/ErrorCode&gt;
    &lt;ErrorDetails xmlns:a=&quot;http://schemas.datacontract.org/2004/07/System.Collections.Generic&quot;&gt;
      &lt;KeyValuePairOfstringanyType&gt;
        &lt;a:key&gt;ApiExceptionSourceKey&lt;/a:key&gt;
        &lt;a:value i:type=&quot;b:string&quot; xmlns:b=&quot;http://www.w3.org/2001/XMLSchema&quot;&gt;Plugin/Microsoft.Crm.ObjectModel.PluginAssemblyService&lt;/a:value&gt;
      &lt;/KeyValuePairOfstringanyType&gt;
      &lt;KeyValuePairOfstringanyType&gt;
        &lt;a:key&gt;ApiSourceActivityKey&lt;/a:key&gt;
        &lt;a:value i:type=&quot;b:string&quot; xmlns:b=&quot;http://www.w3.org/2001/XMLSchema&quot;&gt;Microsoft.Crm.Extensibility.PipelineStep&lt;/a:value&gt;
      &lt;/KeyValuePairOfstringanyType&gt;
      &lt;KeyValuePairOfstringanyType&gt;
        &lt;a:key&gt;ApiExceptionOwnerKey&lt;/a:key&gt;
        &lt;a:value i:type=&quot;b:string&quot; xmlns:b=&quot;http://www.w3.org/2001/XMLSchema&quot;&gt;COMMONDATASERVICECDS\CDSAPI-Reliability&lt;/a:value&gt;
      &lt;/KeyValuePairOfstringanyType&gt;
      &lt;KeyValuePairOfstringanyType&gt;
        &lt;a:key&gt;ApiOriginalExceptionKey&lt;/a:key&gt;
        &lt;a:value i:type=&quot;b:string&quot; xmlns:b=&quot;http://www.w3.org/2001/XMLSchema&quot;&gt;Microsoft.Crm.CrmException: Unable to load plug-in assembly. ---&amp;gt; Microsoft.Crm.CrmException: Unable to load plug-in assembly.
     at Microsoft.Crm.ObjectModel.PluginAssemblyServiceInternal`1.LoadCrmPluginAssemblyMetadata(IBusinessEntity pluginAssembly, IExecutionContext context, Boolean loadAllMetadata)
     at Microsoft.Crm.ObjectModel.PluginAssemblyServiceInternal`1.RetrieveAssemblyMetadata(IBusinessEntity pluginAssembly, ExecutionContext context, Boolean retrieveFromExisting, Boolean forSystemAssembly)
     at Microsoft.Crm.ObjectModel.PluginAssemblyServiceInternal`1.ValidateOperation(String operationName, IBusinessEntity entity, ExecutionContext context)
     at Microsoft.Crm.ObjectModel.SdkEntityServiceBase.CreateInternal(IBusinessEntity entity, ExecutionContext context, Boolean verifyAction)
     --- End of inner exception stack trace ---
     at Microsoft.Crm.Extensibility.VersionedPluginProxyStepBase.Execute(PipelineExecutionContext context)
     at Microsoft.Crm.Extensibility.PipelineInstrumentationHelper.Execute(Boolean instrumentationEnabled, String stopwatchName, ExecuteWithInstrumentation action, PipelineExecutionContext context)
     at Microsoft.Crm.Extensibility.Pipeline.&amp;lt;&amp;gt;c__DisplayClass7_0.&amp;lt;RunStep&amp;gt;b__0()&lt;/a:value&gt;
      &lt;/KeyValuePairOfstringanyType&gt;
      &lt;KeyValuePairOfstringanyType&gt;
        &lt;a:key&gt;ApiStepKey&lt;/a:key&gt;
        &lt;a:value i:type=&quot;b:guid&quot; xmlns:b=&quot;http://schemas.microsoft.com/2003/10/Serialization/&quot;&gt;3ecabb1b-ea3e-db11-86a7-000a3a5473e8&lt;/a:value&gt;
      &lt;/KeyValuePairOfstringanyType&gt;
      &lt;KeyValuePairOfstringanyType&gt;
        &lt;a:key&gt;ApiDepthKey&lt;/a:key&gt;
        &lt;a:value i:type=&quot;b:int&quot; xmlns:b=&quot;http://www.w3.org/2001/XMLSchema&quot;&gt;1&lt;/a:value&gt;
      &lt;/KeyValuePairOfstringanyType&gt;
      &lt;KeyValuePairOfstringanyType&gt;
        &lt;a:key&gt;ApiActivityIdKey&lt;/a:key&gt;
        &lt;a:value i:type=&quot;b:guid&quot; xmlns:b=&quot;http://schemas.microsoft.com/2003/10/Serialization/&quot;&gt;9e6ed737-8374-464e-956a-d70b46a2c686&lt;/a:value&gt;
      &lt;/KeyValuePairOfstringanyType&gt;
      &lt;KeyValuePairOfstringanyType&gt;
        &lt;a:key&gt;ApiPluginSolutionNameKey&lt;/a:key&gt;
        &lt;a:value i:type=&quot;b:string&quot; xmlns:b=&quot;http://www.w3.org/2001/XMLSchema&quot;&gt;System&lt;/a:value&gt;
      &lt;/KeyValuePairOfstringanyType&gt;
      &lt;KeyValuePairOfstringanyType&gt;
        &lt;a:key&gt;ApiStepSolutionNameKey&lt;/a:key&gt;
        &lt;a:value i:type=&quot;b:string&quot; xmlns:b=&quot;http://www.w3.org/2001/XMLSchema&quot;&gt;System&lt;/a:value&gt;
      &lt;/KeyValuePairOfstringanyType&gt;
      &lt;KeyValuePairOfstringanyType&gt;
        &lt;a:key&gt;ApiExceptionCategory&lt;/a:key&gt;
        &lt;a:value i:type=&quot;b:string&quot; xmlns:b=&quot;http://www.w3.org/2001/XMLSchema&quot;&gt;SystemFailure&lt;/a:value&gt;
      &lt;/KeyValuePairOfstringanyType&gt;
      &lt;KeyValuePairOfstringanyType&gt;
        &lt;a:key&gt;ApiExceptionMessageName&lt;/a:key&gt;
        &lt;a:value i:type=&quot;b:string&quot; xmlns:b=&quot;http://www.w3.org/2001/XMLSchema&quot;&gt;UnableToLoadPluginAssembly&lt;/a:value&gt;
      &lt;/KeyValuePairOfstringanyType&gt;
      &lt;KeyValuePairOfstringanyType&gt;
        &lt;a:key&gt;ApiExceptionHttpStatusCode&lt;/a:key&gt;
        &lt;a:value i:type=&quot;b:int&quot; xmlns:b=&quot;http://www.w3.org/2001/XMLSchema&quot;&gt;500&lt;/a:value&gt;
      &lt;/KeyValuePairOfstringanyType&gt;
      &lt;KeyValuePairOfstringanyType&gt;
        &lt;a:key&gt;0&lt;/a:key&gt;
        &lt;a:value i:type=&quot;b:string&quot; xmlns:b=&quot;http://www.w3.org/2001/XMLSchema&quot;&gt;Failed to load plugin assembly with exception Microsoft.Crm.CrmException: GetAssemblyMetadata: expected mdtAssemblyRef or mdtAssembly
     at Microsoft.Crm.CrmException.Assert(Boolean condition, String message)
     at Microsoft.Crm.CrmPluginAssemblyMetadata.GetAssemblyMetadata(UInt32 token)
     at Microsoft.Crm.CrmPluginAssemblyMetadata.ProcessTypeRef(UInt32 typeRef)
     at Microsoft.Crm.CrmPluginAssemblyMetadata.ProcessType(UInt32 token)
     at Microsoft.Crm.CrmPluginAssemblyMetadata.ProcessTypeDef(UInt32 typeDef)
     at Microsoft.Crm.CrmPluginAssemblyMetadata.ProcessType(UInt32 token)
     at Microsoft.Crm.CrmPluginAssemblyMetadata.LoadMetadata()
     at Microsoft.Crm.CrmPluginAssemblyMetadata.LoadMetadataFromAssemblyContent(ArraySegment`1 assemblyContents, Boolean loadAllMetadata)
     at Microsoft.Crm.CrmPluginAssemblyMetadata.LoadMetadataFromAssemblyContent(String content, Boolean loadAllMetadata)
     at Microsoft.Crm.ObjectModel.PluginAssemblyServiceInternal`1.LoadCrmPluginAssemblyMetadata(IBusinessEntity pluginAssembly, IExecutionContext context, Boolean loadAllMetadata). PluginInfo =&amp;gt; Crm plugin assembly info : sourcetype = 0, description = , ismanaged = False, pluginassemblyid = b77380cb-8676-45b6-9e5c-63a5960ed2ac, ispasswordset = False, publickeytoken = 7F66FA42F6885FDC, name = merged, culture = neutral, isolationmode = 2, version = 1.0.0.0, &lt;/a:value&gt;
      &lt;/KeyValuePairOfstringanyType&gt;
      &lt;KeyValuePairOfstringanyType&gt;
        &lt;a:key&gt;1&lt;/a:key&gt;
        &lt;a:value i:type=&quot;b:string&quot; xmlns:b=&quot;http://www.w3.org/2001/XMLSchema&quot;&gt;Microsoft.Crm.CrmException: GetAssemblyMetadata: expected mdtAssemblyRef or mdtAssembly
     at Microsoft.Crm.CrmException.Assert(Boolean condition, String message)
     at Microsoft.Crm.CrmPluginAssemblyMetadata.GetAssemblyMetadata(UInt32 token)
     at Microsoft.Crm.CrmPluginAssemblyMetadata.ProcessTypeRef(UInt32 typeRef)
     at Microsoft.Crm.CrmPluginAssemblyMetadata.ProcessType(UInt32 token)
     at Microsoft.Crm.CrmPluginAssemblyMetadata.ProcessTypeDef(UInt32 typeDef)
     at Microsoft.Crm.CrmPluginAssemblyMetadata.ProcessType(UInt32 token)
     at Microsoft.Crm.CrmPluginAssemblyMetadata.LoadMetadata()
     at Microsoft.Crm.CrmPluginAssemblyMetadata.LoadMetadataFromAssemblyContent(ArraySegment`1 assemblyContents, Boolean loadAllMetadata)
     at Microsoft.Crm.CrmPluginAssemblyMetadata.LoadMetadataFromAssemblyContent(String content, Boolean loadAllMetadata)
     at Microsoft.Crm.ObjectModel.PluginAssemblyServiceInternal`1.LoadCrmPluginAssemblyMetadata(IBusinessEntity pluginAssembly, IExecutionContext context, Boolean loadAllMetadata)&lt;/a:value&gt;
      &lt;/KeyValuePairOfstringanyType&gt;
    &lt;/ErrorDetails&gt;
    &lt;HelpLink&gt;http://go.microsoft.com/fwlink/?LinkID=398563&amp;amp;error=Microsoft.Crm.CrmException%3a80044191&amp;amp;client=platform&lt;/HelpLink&gt;
    &lt;Message&gt;Unable to load plug-in assembly.&lt;/Message&gt;
    &lt;Timestamp&gt;2021-04-29T17:46:08.9958593Z&lt;/Timestamp&gt;
    &lt;ExceptionRetriable&gt;false&lt;/ExceptionRetriable&gt;
    &lt;ExceptionSource i:nil=&quot;true&quot; /&gt;
    &lt;InnerFault&gt;
      &lt;ActivityId&gt;9e6ed737-8374-464e-956a-d70b46a2c686&lt;/ActivityId&gt;
      &lt;ErrorCode&gt;-2147204719&lt;/ErrorCode&gt;
      &lt;ErrorDetails xmlns:a=&quot;http://schemas.datacontract.org/2004/07/System.Collections.Generic&quot; /&gt;
      &lt;HelpLink i:nil=&quot;true&quot; /&gt;
      &lt;Message&gt;Unable to load plug-in assembly.&lt;/Message&gt;
      &lt;Timestamp&gt;2021-04-29T17:46:08.9958593Z&lt;/Timestamp&gt;
      &lt;ExceptionRetriable&gt;false&lt;/ExceptionRetriable&gt;
      &lt;ExceptionSource i:nil=&quot;true&quot; /&gt;
      &lt;InnerFault i:nil=&quot;true&quot; /&gt;
      &lt;OriginalException i:nil=&quot;true&quot; /&gt;
      &lt;TraceText i:nil=&quot;true&quot; /&gt;
    &lt;/InnerFault&gt;
    &lt;OriginalException i:nil=&quot;true&quot; /&gt;
    &lt;TraceText i:nil=&quot;true&quot; /&gt;
  &lt;/OrganizationServiceFault&gt;
  
  Server stack trace: 
     at System.ServiceModel.Channels.ServiceChannel.HandleReply(ProxyOperationRuntime operation, ProxyRpc&amp; rpc)
     at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
     at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
     at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
  
  Exception rethrown at [0]: 
     at Microsoft.Crm.Tools.Libraries.RegistrationHelper.RegisterAssembly(CrmOrganization org, String pathToAssembly, CrmPluginAssembly assembly) in D:\a\1\s\src\GeneralTools\PluginRegistrationV3\PluginRegistration\CrmLibraries\RegistrationHelper.cs:line 723
     at Microsoft.Crm.Tools.AssemblyRegistration.PluginRegistrationViewModel.RegisterAssembly() in D:\a\1\s\src\GeneralTools\PluginRegistrationV3\RegistrationTools\AssemblyRegistration\ViewModels\PluginRegistrationViewModel.cs:line 649
  </code></pre>
  <p>If anyone has had success using a .bat script to run ILMerge, merging .dll files, and using the output to register a D365 Plugin, please let me know!  (extremely specific... I know haha)</p>
  <h2>Update</h2>
  <p>I've now switched to ILRepack and ILRepack.Lib.MSBuild.Task.  I'm using the following config in a ILRepack.targets file:</p>
  <pre><code>&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; ?&gt;
  &lt;Project xmlns=&quot;http://schemas.microsoft.com/developer/msbuild/2003&quot;&gt;
    &lt;Target Name=&quot;ILRepacker&quot; AfterTargets=&quot;Build&quot;&gt;
      &lt;ItemGroup&gt;
        &lt;InputAssemblies Include=&quot;$(OutputPath)$(TargetName)$(TargetExt)&quot; /&gt;
        &lt;!--&lt;InputAssemblies Include=&quot;$(OutputPath)\*.dll&quot; /&gt;--&gt;
        &lt;InputAssemblies Include=&quot;$(OutputPath)adtplugin.dll&quot; /&gt;
        &lt;InputAssemblies Include=&quot;$(OutputPath)Azure.Core.dll&quot; /&gt;
        &lt;InputAssemblies Include=&quot;$(OutputPath)Azure.DigitalTwins.Core.dll&quot;/&gt;
        &lt;InputAssemblies Include=&quot;$(OutputPath)Azure.Identity.dll&quot;/&gt;
        &lt;InputAssemblies Include=&quot;$(OutputPath)Microsoft.Bcl.AsyncInterfaces.dll&quot;/&gt;
        &lt;InputAssemblies Include=&quot;$(OutputPath)System.Memory.dll&quot;/&gt;
        &lt;InputAssemblies Include=&quot;$(OutputPath)System.Threading.Tasks.Extensions.dll&quot;/&gt;
        &lt;!--&lt;InputAssemblies Include=&quot;$(OutputPath)Microsoft.Identity.Client.dll&quot;/&gt;
        &lt;InputAssemblies Include=&quot;$(OutputPath)Microsoft.Identity.Client.Extensions.Msal.dll&quot;/&gt;
        &lt;InputAssemblies Include=&quot;$(OutputPath)Microsoft.Win32.Primitives.dll&quot;/&gt;
        &lt;InputAssemblies Include=&quot;$(OutputPath)netstandard.dll&quot;/&gt;--&gt;
        
      &lt;/ItemGroup&gt;
  
      &lt;ILRepack
          Parallel=&quot;true&quot;
          Internalize=&quot;false&quot;
          InternalizeExclude=&quot;@(DoNotInternalizeAssemblies)&quot;
          InputAssemblies=&quot;@(InputAssemblies)&quot;
          LibraryPath=&quot;$(OutputPath)&quot;
          Wildcards=&quot;false&quot;
          TargetKind=&quot;SameAsPrimaryAssembly&quot;
          DebugInfo=&quot;false&quot;
          KeyFile=&quot;adtplugin.snk&quot;
          OutputFile=&quot;$(OutputPath)Merged\$(AssemblyName).dll&quot;
          LogFile=&quot;$(OutputPath)Merged\ILRepack.log&quot;
      /&gt;
    &lt;/Target&gt;
  &lt;/Project&gt;
  </code></pre>
  <p>The merge succeeds, but the plugin registration is still failing with the same error dump shown above.</p>