使用Mono.Cecil注入GeneratedCodeAttribute

时间:2011-01-17 10:44:54

标签: c# mono mono.cecil

我正在使用Mono.Cecil来管理我的.net 2.0程序集。 在操作之后,我想通过注入模块属性

将程序集标记为已处理
var stringType = _module.Import(typeof(string));
var baseCtor = _module.Import(typeof(GeneratedCodeAttribute).GetConstructor(new[] { typeof(string), typeof(string) }));
var result = new CustomAttribute(baseCtor);
result.ConstructorArguments.Add(new CustomAttributeArgument(stringType, "ProcessedBySomething"));
result.ConstructorArguments.Add(new CustomAttributeArgument(stringType, "1.0"));

保存程序集后,它变得依赖于.net 4.0,因为操作app是用.net 4.0编写的。 GeneratedCodeAttribute存在于.net 2.0中,所以我做错了什么?

1 个答案:

答案 0 :(得分:6)

你猜对了。由于操作应用程序在.net 4.0上运行,typeof是运行时功能,因此它将返回当前运行时版本的类型。

要修复它,最简单的方法是使用Cecil打开程序集,为正在修改的模块引用的mscorlib版本创建引用。您的代码将成为:

var stringType = _module.TypeSystem.String;
var corlib = (AssemblyNameReference) _module.TypeSystem.Corlib;
var system = _module.AssemblyResolver.Resolve (new AssemblyNameReference ("System", corlib.Version) {
    PublicKeyToken = corlib.PublicKeyToken,
});
var generatedCodeAttribute = system.MainModule.GetType ("System.CodeDom.Compiler.GeneratedCodeAttribute");
var generatedCodeCtor = generatedCodeAttribute.Methods.First (m => m.IsConstructor && m.Parameters.Count == 2);

var result = new CustomAttribute (_module.Import (generatedCodeCtor));
result.ConstructorArguments.Add(new CustomAttributeArgument(stringType, "ProcessedBySomething"));
result.ConstructorArguments.Add(new CustomAttributeArgument(stringType, "1.0"));