Tri*_*ian 9 .net reflection.emit portable-class-library
我正在编写一个使用System.Reflection.Emit
API 生成磁盘上.NET程序集的编译器.编译器本身是针对.NET 4.5构建的,但生成的代码仅引用可移植类库中的类型.但是,当尝试从Windows Phone 8项目引用生成的程序集时,Visual Studio会抱怨这一点A reference to a higher version or incompatible assembly cannot be added to the project
.
在反编译器中打开生成的程序集时,我可以看到它引用了两个PCL加上mscorlib 4.0.0.0
,而我理解PCL应该引用mscorlib 2.0.5.0
.
有没有办法让System.Reflection.Emit
API生成PCL,或者是我唯一的选择迁移到Mono.Cecil
?
好的,我会回答我自己的问题.
我没有发现任何证据表明System.Reflection.Emit
API可以生成引用另一个版本的程序集,而mscorlib
不是当前进程使用的版本.实际上,带System.Type
参数和其他反射对象的API 可能会添加对查询其Type.Assembly
属性的结果的引用,这与使用中的版本相对应mscorlib
.
但是,可移植类库与System.Reflection.Emit
生成的库没有什么不同,因此可以在事件之后修补程序集以"使它们可移植".免责声明:这需要熟悉PE文件格式,可能会产生无法预料的副作用,但它对我有用:
生成程序集时,用于AssemblyBuilder.SetCustomAttribute
将此属性添加到程序集:
[System.Runtime.Versioning.TargetFrameworkAttribute(".NETPortable,Version=v4.0,Profile=Profile136", FrameworkDisplayName = ".NET Portable Subset")]
Run Code Online (Sandbox Code Playgroud)这是粗略的地方:在调用之后AssemblyBuilder.Save
,打开读/写文件流到生成的程序集,遍历PE,COFF,COM,CLI和元数据表头以找到AssemblyRef
表行mscorlib
.修改mscorlib
to 的引用版本2.0.5.0
,添加0x100
到其标志("retargetable")并将其公钥标记blob更新为0x7CEC85D7BEA7798E
.
请注意,如果您使用其他框架程序集,您可能还需要修补它们的引用(我没有对此进行测试).不然,瞧!该程序集现在是可移植的,例如,可以在Windows Phone项目中使用.
(...或只是使用Mono.Cecil
/ IKVM.Reflection
...)
编辑:我使用的代码可以在github上找到.这是一个巨大的黑客,所以通常的免责声明适用,使用风险自负.
归档时间: |
|
查看次数: |
545 次 |
最近记录: |