微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

ILMerge / ILRepack dll 无法使用 Dynamics 365 插件注册工具注册

如何解决ILMerge / ILRepack dll 无法使用 Dynamics 365 插件注册工具注册

我正在尝试为 D365 创建一个插件我有包依赖项,包括

  • Azure.DigitalTwins.Core
  • Azure.Core
  • Azure.Identity

必须将这些 .dll 依赖项合并到单个 .dll 中才能注册插件。我正在使用 ILMerge 批处理文件脚本将这些 dll 组合成单个 merged.dll 输出

这是我正在使用的脚本:

@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> 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 "%ILMERGE_PATH%"\ILMerge.exe

SET PROJECT_ROOT=%CD%
SET ASSEMBLY_DIR=%PROJECT_ROOT%\bin\Debug\net462

::/targetplatform:v4,"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0" ^
::/target:library ^
::/copyattrs ^
::/closed ^
::/allowDup ^

echo Merging adtplugin...
:: add project DLL's starting with replacing the FirstLib with this project's DLL
"%ILMERGE_PATH%"\ILMerge.exe ^
/keyfile:%PROJECT_ROOT%\adtplugin.snk ^
/out:%ILMERGE_BUILD%\merged.dll ^
/target:library ^
/nDebug ^
/closed ^
/allowDup ^
/copyattrs ^
/targetplatform:v4,"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.7.2" ^
%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

我对传递给 ILMerge.exe 的 /option 标志进行了相当多的尝试。目前,通过显示的配置,我可以将列出的 .dll 合并到单个 merge.dll 输出中。

接下来,我尝试使用插件注册工具通过 merged.dll 输出文件注册新程序集。当我尝试注册插件时出现错误

Plug-in registration tool

这是错误转储:

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: <OrganizationServiceFault xmlns="http://schemas.microsoft.com/xrm/2011/Contracts" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
  <ActivityId>9e6ed737-8374-464e-956a-d70b46a2c686</ActivityId>
  <ErrorCode>-2147204719</ErrorCode>
  <ErrorDetails xmlns:a="http://schemas.datacontract.org/2004/07/System.Collections.Generic">
    <keyvaluePairOfstringanyType>
      <a:key>ApiExceptionSourceKey</a:key>
      <a:value i:type="b:string" xmlns:b="http://www.w3.org/2001/XMLSchema">Plugin/Microsoft.Crm.ObjectModel.PluginAssemblyService</a:value>
    </keyvaluePairOfstringanyType>
    <keyvaluePairOfstringanyType>
      <a:key>ApiSourceActivityKey</a:key>
      <a:value i:type="b:string" xmlns:b="http://www.w3.org/2001/XMLSchema">Microsoft.Crm.Extensibility.Pipelinestep</a:value>
    </keyvaluePairOfstringanyType>
    <keyvaluePairOfstringanyType>
      <a:key>ApiExceptioNownerKey</a:key>
      <a:value i:type="b:string" xmlns:b="http://www.w3.org/2001/XMLSchema">COMMONDATASERVICECDS\CDSAPI-Reliability</a:value>
    </keyvaluePairOfstringanyType>
    <keyvaluePairOfstringanyType>
      <a:key>ApiOriginalExceptionKey</a:key>
      <a:value i:type="b:string" xmlns:b="http://www.w3.org/2001/XMLSchema">Microsoft.Crm.CrmException: Unable to load plug-in assembly. ---&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,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.&lt;&gt;c__displayClass7_0.&lt;RunStep&gt;b__0()</a:value>
    </keyvaluePairOfstringanyType>
    <keyvaluePairOfstringanyType>
      <a:key>ApiStepKey</a:key>
      <a:value i:type="b:guid" xmlns:b="http://schemas.microsoft.com/2003/10/Serialization/">3ecabb1b-ea3e-db11-86a7-000a3a5473e8</a:value>
    </keyvaluePairOfstringanyType>
    <keyvaluePairOfstringanyType>
      <a:key>ApiDepthKey</a:key>
      <a:value i:type="b:int" xmlns:b="http://www.w3.org/2001/XMLSchema">1</a:value>
    </keyvaluePairOfstringanyType>
    <keyvaluePairOfstringanyType>
      <a:key>ApiActivityIdKey</a:key>
      <a:value i:type="b:guid" xmlns:b="http://schemas.microsoft.com/2003/10/Serialization/">9e6ed737-8374-464e-956a-d70b46a2c686</a:value>
    </keyvaluePairOfstringanyType>
    <keyvaluePairOfstringanyType>
      <a:key>ApiPluginSolutionNameKey</a:key>
      <a:value i:type="b:string" xmlns:b="http://www.w3.org/2001/XMLSchema">System</a:value>
    </keyvaluePairOfstringanyType>
    <keyvaluePairOfstringanyType>
      <a:key>ApiStepSolutionNameKey</a:key>
      <a:value i:type="b:string" xmlns:b="http://www.w3.org/2001/XMLSchema">System</a:value>
    </keyvaluePairOfstringanyType>
    <keyvaluePairOfstringanyType>
      <a:key>ApiExceptionCategory</a:key>
      <a:value i:type="b:string" xmlns:b="http://www.w3.org/2001/XMLSchema">SystemFailure</a:value>
    </keyvaluePairOfstringanyType>
    <keyvaluePairOfstringanyType>
      <a:key>ApiExceptionMessageName</a:key>
      <a:value i:type="b:string" xmlns:b="http://www.w3.org/2001/XMLSchema">UnabletoLoadpluginAssembly</a:value>
    </keyvaluePairOfstringanyType>
    <keyvaluePairOfstringanyType>
      <a:key>ApiExceptionHttpStatusCode</a:key>
      <a:value i:type="b:int" xmlns:b="http://www.w3.org/2001/XMLSchema">500</a:value>
    </keyvaluePairOfstringanyType>
    <keyvaluePairOfstringanyType>
      <a:key>0</a:key>
      <a:value i:type="b:string" xmlns:b="http://www.w3.org/2001/XMLSchema">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,Boolean loadAllMetadata). PluginInfo =&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,</a:value>
    </keyvaluePairOfstringanyType>
    <keyvaluePairOfstringanyType>
      <a:key>1</a:key>
      <a:value i:type="b:string" xmlns:b="http://www.w3.org/2001/XMLSchema">Microsoft.Crm.CrmException: GetAssemblyMetadata: expected mdtAssemblyRef or mdtAssembly
   at Microsoft.Crm.CrmException.Assert(Boolean condition,Boolean loadAllMetadata)</a:value>
    </keyvaluePairOfstringanyType>
  </ErrorDetails>
  <HelpLink>http://go.microsoft.com/fwlink/?LinkID=398563&amp;error=Microsoft.Crm.CrmException%3a80044191&amp;client=platform</HelpLink>
  <Message>Unable to load plug-in assembly.</Message>
  <Timestamp>2021-04-29T17:46:08.9958593Z</Timestamp>
  <ExceptionRetriable>false</ExceptionRetriable>
  <ExceptionSource i:nil="true" />
  <InnerFault>
    <ActivityId>9e6ed737-8374-464e-956a-d70b46a2c686</ActivityId>
    <ErrorCode>-2147204719</ErrorCode>
    <ErrorDetails xmlns:a="http://schemas.datacontract.org/2004/07/System.Collections.Generic" />
    <HelpLink i:nil="true" />
    <Message>Unable to load plug-in assembly.</Message>
    <Timestamp>2021-04-29T17:46:08.9958593Z</Timestamp>
    <ExceptionRetriable>false</ExceptionRetriable>
    <ExceptionSource i:nil="true" />
    <InnerFault i:nil="true" />
    <OriginalException i:nil="true" />
    <TraceText i:nil="true" />
  </InnerFault>
  <OriginalException i:nil="true" />
  <TraceText i:nil="true" />
</OrganizationServiceFault>

Server stack trace: 
   at System.ServiceModel.Channels.ServiceChannel.HandleReply(ProxyOperationRuntime operation,ProxyRpc& 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

如果有人成功使用 .bat 脚本运行 ILMerge、合并 .dll 文件并使用输出注册 D365 插件,请告诉我! (非常具体...我知道哈哈)

更新

我现在已经切换到 ILRepack 和 ILRepack.Lib.MSBuild.Task。我在 ILRepack.targets 文件中使用以下配置:

<?xml version="1.0" encoding="utf-8" ?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Target Name="ILRepacker" AfterTargets="Build">
    <ItemGroup>
      <InputAssemblies Include="$(OutputPath)$(TargetName)$(TargetExt)" />
      <!--<InputAssemblies Include="$(OutputPath)\*.dll" />-->
      <InputAssemblies Include="$(OutputPath)adtplugin.dll" />
      <InputAssemblies Include="$(OutputPath)Azure.Core.dll" />
      <InputAssemblies Include="$(OutputPath)Azure.DigitalTwins.Core.dll"/>
      <InputAssemblies Include="$(OutputPath)Azure.Identity.dll"/>
      <InputAssemblies Include="$(OutputPath)Microsoft.Bcl.AsyncInterfaces.dll"/>
      <InputAssemblies Include="$(OutputPath)system.memory.dll"/>
      <InputAssemblies Include="$(OutputPath)System.Threading.Tasks.Extensions.dll"/>
      <!--<InputAssemblies Include="$(OutputPath)Microsoft.Identity.Client.dll"/>
      <InputAssemblies Include="$(OutputPath)Microsoft.Identity.Client.Extensions.Msal.dll"/>
      <InputAssemblies Include="$(OutputPath)Microsoft.Win32.Primitives.dll"/>
      <InputAssemblies Include="$(OutputPath)netstandard.dll"/>-->
      
    </ItemGroup>

    <ILRepack
        Parallel="true"
        Internalize="false"
        InternalizeExclude="@(DonotinternalizeAssemblies)"
        InputAssemblies="@(InputAssemblies)"
        LibraryPath="$(OutputPath)"
        Wildcards="false"
        TargetKind="SameAsPrimaryAssembly"
        DebugInfo="false"
        KeyFile="adtplugin.snk"
        OutputFile="$(OutputPath)Merged\$(AssemblyName).dll"
        LogFile="$(OutputPath)Merged\ILRepack.log"
    />
  </Target>
</Project>

合并成功,但插件注册仍然失败,并出现上述相同的错误转储。

解决方法

您可能希望避免合并属于 .NET Framework 的任何内容(我假设像 System.MemorySystem.Threading.Tasks 这样的库是)。

话虽如此,根据您要合并的 DLL,即使您注册了它,根据代码的实际作用,sandbox environment 的限制可能会阻止插件运行。

>

如果情况确实如此,您可能需要查看 Azure Aware Plugin

我曾经有一个插件,我必须在其中进行 RSA 签名验证。我尝试使用 .NET 库,但沙箱禁止运行与 RSA 相关的代码。我最终不得不使用我发现的名为 EZ-RSA 的开源 RSA 库“自行开发”。

感谢您的更新。我更仔细地查看了错误消息。我发现 this articlethis question 中,开发人员似乎得出结论,ILMerging an Identity library 是个大杂烩。

就合并/重新打包路径而言,您可能希望使用一个空白项目并一个一个地合并 DLL,在每个 DLL 之后测试插件注册以查看哪个或哪些库破坏了注册。>

我最后一次听说,即使它有效,ILMerge 在技术上也不受支持。支持的是 Azure Aware 插件。

您可以注册您的插件以在它触发时调用服务端点或网络钩子:
reg1

对于服务端点,它可以访问 Azure 服务总线队列中的各种类型的侦听器(通过连接字符串或此配置对话框)。 service endpoint

调用 Webhook 也是一种选择: webhook

,

尝试在构建操作后使用 Fody 包合并您的 .dll-s。首先,您需要通过 nuget 安装 FodyCostura.Fody。它将添加一些引用和文件 FodyWeavers.xml,您可以通过这种方式填充

<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
  <Costura />
</Weavers>

然后在解决方案资源管理器中选择要合并在一起的程序集的引用,并在属性窗口中更改复制本地 strong> 到 True。对于那些您不想包含在合并过程中的程序集,请选择 Copy Local - False

重新构建您的解决方案,在输出中您将获得合并的 dll。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。