所以我正在使用 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 不直接使用这个呢?
非常感谢任何帮助!