无法使用单色塞西尔设置类型的基类
本文关键字:置类型 基类 单色塞 | 更新日期: 2023-09-27 18:33:46
我正在尝试使用Mono Cecil来操作DLL。我想做的是将某些类的基本类型设置为从mscorlib.dll
System.MarshalByRefObject
。我正在使用以下代码。
var assembly = AssemblyDefinition.ReadAssembly(inputtarget);
var types = assembly.MainModule.Types;
var myTypesToChange = types.Where(...).Select(t => t);
var baseType = AssemblyDefinition.ReadAssembly(@"C:'Windows'Microsoft.NET'Framework64'v4.0.30319'mscorlib.dll").MainModule.Types.Where(t => t.Name.Contains("MarshalByRefObject")).Select(t => t).First();
foreach (var myType in myTypesToChange)
{
myType.BaseType = baseType;
}
assembly.Write(outputtarget);
在输出中未设置基本类型!
当我将BaseType
设置为从现有程序集中选择的TypeReference
时,它正在正确设置基本类型。
我相信我所做的与在回复有关代码项目文章"使用 Mono.Cecil 重新编织 IL 代码"的评论中所建议的方式非常相似:
"是的,您可以重写任何类的基本类型:"
var assembly = AssemblyDefinition.ReadAssembly(AssemblyPath); var mainModule = assembly.MainModule; var companyType = mainModule.Types.First(t => t.Name == "Company"); var ownerType = mainModule.Types.First(t => t.Name == "Owner"); ownerType.BaseType = companyType; assembly.Write(AssemblyPath);
这应该很容易!我做错了什么?
问题是没有考虑程序集元数据。每个程序集都有元数据,其中包含与程序集引用和类型用法相关的信息。
你要做的是在mainModule中导入MarshalByRefObject类型:
var assembly = assemblyDef.AssemblyDefinition;
var types = assembly.MainModule.Types;
var myTypesToChange = types.Select(t => t);
var baseType = AssemblyDefinition.ReadAssembly(@"C:'Windows'Microsoft.NET'Framework64'v4.0.30319'mscorlib.dll").MainModule.Types.Where(t => t.Name.Contains("MarshalByRefObject")).Select(t => t).First();
foreach (var myType in myTypesToChange)
{
myType.BaseType = mainModule.Import(baseType);
}
除了扩展元数据之外,还必须更改构造函数的 CIL 代码以调用新基类的构造函数而不是原始基类。
最后,一个建议。我认为 MarshalByRefObject 的 TypeReference 可以用更优雅的方式提取:
var baseType = mainModule.Import(typeof (MarshalByRefObject));
for (...)
{
myType.BaseType = baseType;
}