1

所以我正在使用 ILRepack,据我所知,它在幕后使用 Mono.Cecil 来进行 ILWeaving。我在我的项目中遇到了一个问题,一旦我导入就会导致以下错误,例如 Newtonsoft.Json 版本 13.0.1:

INFO: Writing output assembly to disk
System.ArgumentException: Member 'System.Void System.Runtime.CompilerServices.NullableAttribute::.ctor(System.Byte)' is declared in another module and needs to be imported
   at Mono.Cecil.MetadataBuilder.LookupToken(IMetadataTokenProvider provider)
   at Mono.Cecil.MetadataBuilder.AddCustomAttributes(ICustomAttributeProvider owner)
   at Mono.Cecil.MetadataBuilder.AddConstraints(GenericParameter generic_parameter, GenericParamConstraintTable table)
   at Mono.Cecil.MetadataBuilder.AddGenericParameters()
   at Mono.Cecil.MetadataBuilder.BuildTypes()
   at Mono.Cecil.MetadataBuilder.BuildModule()
   at Mono.Cecil.MetadataBuilder.BuildMetadata()
   at Mono.Cecil.ModuleWriter.BuildMetadata(ModuleDefinition module, MetadataBuilder metadata)
   at Mono.Cecil.ModuleWriter.Write(ModuleDefinition module, Disposable`1 stream, WriterParameters parameters)
   at Mono.Cecil.ModuleWriter.WriteModule(ModuleDefinition module, Disposable`1 stream, WriterParameters parameters)
   at Mono.Cecil.ModuleDefinition.Write(String fileName, WriterParameters parameters)
   at Mono.Cecil.AssemblyDefinition.Write(String fileName, WriterParameters parameters)
   at ILRepacking.ILRepack.Repack()
   at ILRepack.Lib.Task.ILRepack.Execute()

我所做的只是将它添加为 PackageReference,在发布模式下构建时,我收到此错误。

我意识到错误消息非常具体,但是经过数小时的尝试解决此问题后,我无法解决。我最大的问题是我不知道“另一个模块”的确切含义。
这是一个完全空的项目,除了使用 ILRepack 包和导入 Newtonsoft.Json。
它的目标netstandard2.0,我需要成为目标。由于...原因,我无法将其更改为较新的版本。
在没有 Newtonsoft.Json 的情况下以发布模式构建。
它也可以在不执行 ILRepack 的调试中构建。
所以这意味着必要的属性必须存在,否则它不会在调试中编译,对吧?

我尝试在我的项目中手动定义此属性,如下所示:

namespace System.Runtime.CompilerServices
{
    [AttributeUsage(
        AttributeTargets.Class |
        AttributeTargets.Event |
        AttributeTargets.Field |
        AttributeTargets.GenericParameter |
        AttributeTargets.Parameter |
        AttributeTargets.Property |
        AttributeTargets.ReturnValue,
        AllowMultiple = false,
        Inherited = false)]
    public class NullableAttribute : Attribute
    {
        public readonly byte[] NullableFlags;
        public NullableAttribute(byte flag)
        {
            NullableFlags = new byte[] { flag };
        }
        public NullableAttribute(byte[] flags)
        {
            NullableFlags = flags;
        }
    }
}

但即便如此,我还是得到了上述错误。那么Mono.Cecil 到底在哪寻找这个属性呢?为什么在我的项目中手动定义它还不够?

我使用的 ILRepack 配置是这样的:

  <Target Name="MergeTheThing" AfterTargets="build" Condition="$(Configuration.Contains('Release'))">
    <ItemGroup>
      <InputAssemblies Include="$(OutputPath)$(TargetName)$(TargetExt)" />
      <InputAssemblies Include="$(OutputPath)*.dll" Exclude="$(OutputPath)$(TargetName)$(TargetExt)" />
    </ItemGroup>
    <ItemGroup>
      <LibraryPath Include="$(OutputPath)" />
      <LibraryPath Include="$(VINTAGE_STORY)/Lib/" />
    </ItemGroup>
    <ItemGroup>
      <DoNotInternalizeAssemblies Include="VintagestoryAPI.dll" />
      <DoNotInternalizeAssemblies Include="VintagestoryLib.dll" />
      <DoNotInternalizeAssemblies Include="VSSurvivalMod.dll" />
      <DoNotInternalizeAssemblies Include="VSEssentials.dll" />
      <DoNotInternalizeAssemblies Include="VSCreativeMod.dll" />
      <DoNotInternalizeAssemblies Include="Newtonsoft.Json.dll" />
      <DoNotInternalizeAssemblies Include="0Harmony.dll" />
      <DoNotInternalizeAssemblies Include="protobuf-net.dll" />
      <DoNotInternalizeAssemblies Include="System.Data.SQLite.dll" />
    </ItemGroup>
    <ILRepack Parallel="true"
              DebugInfo="true"
              Verbose="true"
              Internalize="true"
              InternalizeExclude="@(DoNotInternalizeAssemblies)"
              Wildcards="true"
              InputAssemblies="@(InputAssemblies)"
              LibraryPath="@(LibraryPath)"
              KeyFile="$(AssemblyOriginatorKeyFile)"
              TargetKind="SameAsPrimaryAssembly"
              OutputFile="$(OutputPath)$(AssemblyName)$(TargetExt)"
              LogFile="output.txt"/>
  </Target>

我有哪些选项可以告诉 Mono.Cecil 在哪里查找此属性?或者我可以以某种方式让它完全忽略该属性吗?我不需要使用它,我只需要它来正确编译。

请参阅附加的 output.txt 以获取日志文件: output.txt
在此日志文件中,我还注意到它实际上确实导入了我手动定义的 NullableAttribute: Importing System.Runtime.CompilerServices.NullableAttribute from TestSolution4.dll,但是为什么 Mono.Cecil 不直接使用这个呢?

非常感谢任何帮助!

4

0 回答 0