1.3 Loading the Common Language Runtime 加载CLR
每个你创建的可执行程序集生成可以是一个可执行应用程序或是一个DLL。当然,CLR负责管理执行这些包含在程序集中的代码。这意味着,.NET Framework必须在主机计算机上安装。微软已经创建了一个再分配包,你在Windows免费安装使用。在有些windows版本中NET框架已经安装。
你可以通过查看在%SystemRoot%\ System32目录下的Mscoree.dll来确定.NET框架是否已经安装。如果这个文件存在,表明.NET Framework已经成功安装。但是,多个版本的.NET Framework可以安装在一台机器同时进行。如果你想确定到底安装了哪个版本的NET框架,检查以下注册表项的子项:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP
NET框架SDK包含一个称为CLRVer.exe的命令行实用工具,它会显示计算机上安装了所有的CLR版本。此实用工具还可以显示哪些版本的CLR进程目前正在运行的机器上使用。
在我们开始讲述CLR是如何加载的之前,我们需要花一点时间讨论32位和64位版本的Windows。如果您的程序集文件只包含类型安全的托管代码,那么你写的代码应该在32位和64位Windows上运行。你的代码不需要任何修改就可以运行在任何版本的Windows。事实上,在32位Windows上编译器产生的EXE / DLL文件同样可以在在x64和IA64 64位版本的Windows上运行!换句话说,一个文件可以在任何安装了.NET框架的机器上运行。
对极少数情况下,开发者会编写只能在特定的Windows版本运行的代码。当针对一个特定的CPU架构使用不安全的代码与非托管代码进行互操作时,开发者可能会这样做。为了帮助这些开发者,在C#编译器提供了一个平台(platform)命令行选择。它允许您指定产生的程序集是否,在x86机器上只运行32位Windows版本, x64计算机上只运行64位Windows,或英特尔安腾机器上只运行64位Windows。如果你不指定一个平台,默认是任何的cpu,也就是说,产生的程序集可以运行在任何版本的Windows上运行。 Visual Studio的用户可以设置显示项目的属性页的一个项目的目标平台,单击生成选项卡,然后选择目标纲要中的一个列表选项(见图1-3)。
根据转换不同平台,C#编译器将生成一个包含PE32或PE32 +头的程序集,编译器也会生成所需的CPU架构(或不可知进入头),以及。微软附带2个SDK命令行工具,DumpBin.exe和CorFlags.exe,你可以用它来检查由编译器产生的托管模块中的头信息。
当运行一个可执行文件时,Windows会检查这个EXE文件的标头,以确定应用程序是否需要32位或64位地址空间。一个有PE32标头的文件可以在32位或64位的地址空间上运行,而一个具有PE32 +标头的文件,只能在64位地址空间上运行。Windows还检查CPU架构内嵌入到header里的信息,以确保它匹配计算机上的CPU类型。最后,Windows的64位版本提供了允许32位Windows应用程序运行的技术。这项技术被称为对Windows64的WOW64(for windows on windows64)。这种技术甚至允许在他们原生的x86代码的32位应用程序在Itanium机器上运行,因为WOW64的技术可以模拟x86指令集,虽然有一个显着的性能成本。
表1-2告诉了我们两件事情。首先,它告诉我们当你选择特定的平台命令行选项,编译器会为你产生那种托管模块。其次,它告诉我们该应用程序将如何运行各种版本的Windows上。
Windows检查完EXE文件的标头后,决定要创建32位进程,一个64位进程,或一个WOW64的过程中,Windows加载的Mscoree.dll的x86,x64或Ia64文件的版本到进程的地址空间。在一个x86的Windows上,x86版本的Mscoree.dll存放在C:\ Windows \ System32目录。在一个x64或Ia64版本的Windows上,x86版本的Mscoree.dll 版本文件会存放在C:\的Windows \ SysWow64目录里,而64位版本(x64或Ia64文件)存放在在C:\的Windows \ System32目录中(向后兼容的原因)。然后,该进程的主线程调用Mscoree.dll的内部定义的方法。这种方法在CLR初始化,加载EXE程序集,然后调用它的入口点方法(main方法)。此时,托管应用程序开始运行。
Note:通过使用版本1.0或1.1 的Microsoft--C#编译器产生一个包含PE32头,且与CPU的体系结构无关的程序集。然而,在加载时,CLR默认这些程序集只能在x86下运行。对于可执行文件,这提高了实际在64位系统工作,因为该可执行文件将在WOW64中加载,使这一进程的环境非常相似,它会在32位的Windows版本。
如果一个非托管的应用程序调用LoadLibrary来加载一个托管程序集时,Windows会加载并且初始化CLR(如果不是已经加载),以便处理在程序集中的代码。当然,在这种情况下,该进程已经启动并运行,这可能限制了程序集的可用性。例如,一个选择了x86平台编译的托管程序集将无法加载到64位进程,但是会被加载到64位版本windows的WoW64上。
作者:石世特
出处:http://www.cnblogs.com/TivonStone/
希望本文对你有所帮助,想转随便转,心情好的话给我的文章留个链接.o(. .)o