昨天不知道怎么搞的,3天没用Windows就给我找茬,所有基于.Net的程序都报错:“由于应用程序配置不正确,程序未能启动”(包括卡巴斯基,MS Office2007,MSN, MS VS2005...)
折腾半天,又是修复系统的,还是没搞定。刚终于百度到一个好方法:
在目标机器安装VCRedist_x86.exe可以解决这个问题。该文件可以在MSDN网站上下载。
Microsoft Visual C++ 2005 Redistributable Package (x86)下载
Microsoft Visual C++ 2005 SP1 Redistributable Package (x86)下载
原因:
一般认为,VC2005编译出来的东西,如果用了atl或者mfc,需要atl80.dll 或者msmfc80.dll,我在一开始的时候也是这么认为的,我把这两个文件放在了path中可以找到的地方。因此用depends看出来是没问题的。
但是事实上,从VC2005开始,(可能2003,但是我没有用过)这些dll是不像以前的程序那样直接被加载进进程的。查看%SYSTEMROOT%\winsxs会发现里面有很多类似于x86_Microsoft.VC80.ATL_1fc8b3b9a1e18e3b_8.0.50727.42_x-ww_6e805841的目录,这些目录里面包含了atl80.dll, msmfc80.dll。然后在manifests 目录里面有对应的manifests:
x86_Microsoft.VC80.ATL_1fc8b3b9a1e18e3b_8.0.50727.42_x-ww_6e805841.manifest
这是VC8的一个改变。VC8编译的程序在运行时加载动态库(crt, mfc, atl )都是放在一个类似全局类型库的地方。不再像以前MS所建议的那样,为了避免dll hell而把动态库放在程序同级目录。而这个全局类型库的地方就是winSxS,同时加载之前还需要有该dll对应的manifest。
具体加载dll的时候为什么需要Manifest我不是很清楚,Visual C++ 2005的 program manager Martyn Lovell在他的blog中有提到要解释这样做的原因,但是至今没有下文:(
暂时能够知道的是,加载dll需要manifest,没有manifest的动态库即使放在path下也不会加载。而VCRedist_x86.exe会帮你把manifest和dll放在正确的地方。



0 评论:
发表评论