.NET 开发者尽早会疑惑这一点:
在Framework从1.1到2.0变化时, 可以通过app.exe.config中配置改变你的程序究竟被哪个CLR版本管理:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v1.1.4322" />
<supportedRuntime version="v2.0.50727" />
<!--
<supportedRuntime version="v3.0" />
<supportedRuntime version="v3.5" />
-->
</startup>
</configuration>
|
但是, VS2008出来了, Framework 3.0和3.5版都出来了, 怎么把它们也加入这个行列?
检查了C:\Windows\Microsoft.NET\Framework 目录下之后, 会发现不同的Framework版本直接拿版本号作目录名, 就是上面的"v1.1.4322"这样的形式.
问题是, 这么写不生效! 证明:
一是在C#代码里这样测试:
class Test
{
public static void Main()
{
string runtime_info = ".NET CLR version: " + System.Runtime.InteropServices.RuntimeEnvironment.GetSystemVersion();
System.Console.WriteLine( runtime_info );
}
}
|
另一个是通过 sysinternals公司的process explorer工具, 可以查看一个程序有哪些DLL被load到其进程空间中, 以全路径名显示DLL在磁盘上的位置. 哪个版本的CLR被使用一看便知.
第一种方法显然更好. 分别用1.1, 2.0, 3.0, 3.5 下的csc.exe工具来编译. 只有1.1版本和2.0版本有区分.
3.0, 3.5 与2.0完全一样!
Framework从1.1升级到2.0 的变化与从2.0升级到3.0, 从3.0升级到3.5是非常不同的事情, 尽管从对外发布的消息上来看无非都是版本升级.
1.1到2.0的升级不是完全向后兼容的, 这意味着用1.1的framework编译出来的assembly不能完全保证能在2.0上运行. 1.1到2.0的升级也同时需要CLR本身的升级, IL中间代码也得添加新的指令比如对模板的表示.
2.0到3.0到3.5, 则是完全向后兼容的, 3.0只是在2.0本身的基础上添加了DLL. 3.5类似.
Framework v3.0的目录下连csc.exe 编译器都没带(没带的原因很可能是安装时检测到我已安装了framework 2.0). 有力证明了它就是把2.0原封不动地作为基础.
Framework v3.5目录下带有csc.exe, 我猜测原因可能是C#语言中加入了新的元素, 如LINQ. 需要更新编译器来提供支持.
所以, 结论是, 不要指望有一个所谓3.0运行时, 可以通过〈supportedRuntime version="v3.0"/〉来指定, 因为3.0无非就是2.0本身, 如果你的C#程序中用到了3.0中新出现的FCL类, 它就是个3.0程序, 如果没有, 它就是2.0. 3.5的情况与此类似.
一个编译好的assembly, 它里面的CLR header记着这个assembly成功运行所需要的最低的CLR版本号. 这个方案隐含着一个假设: 可以在低版本的CLR上运行的一定可以在高版本上运行, 1.1到2.0的升级不是这样!
上面截图是用 ildasm /ALL /OUT=CON | gvim -
得到的. 其中的 Major runtime version和Minor runtime version就是用来指定可以运行该程序的最低CLR版本号. 但是, 注意这里出现的2.5 是个怪物. 它既不是编译器的版本号, 也不是CLR的版本号. 真正的CLR版本号是图中底部的"v2.0.50727". 这是作为assembly的metadata出现的. 我猜想也是CLR loader决定以哪个版本来运行的真正依据所在.
在http://blogs.msdn.com/joshwil/archive/2004/10/15/243019.aspx 中专门讲64bit的CLR运行时问题, 但附带的把我想要搞清楚的问题也讲的非常清楚.
对于所有的微软正式发布的framework版本, 包括v1.0, 上面Major runtime version和Minor runtime version的取值也是2和0, 历史原因造成的错乱. 上文中提到了这两个数据真正起作用的地方是用来决定是否可以以64bit CLR来运行. 不是我在这里关注的重点.
阅读(3488) | 评论(5) | 转发(0) |