在未安装VS2005的机器上运行VS2005的程序,可能会出现如下错误提示:
1)由于应用程序配置不正确,程序未能启动,重新安装应用程序可能会纠正这个问题(Multi-threaded DLL (/MD)选项下生成的代码会产生这个问题)
2)应用程序正常初始化(0xc0150002)失败。请单击“确定”,终止应用程序。(Multi-threaded Debug (/MTd)选项下生成的代码会产生这个问题)
几种可能的解决办法:
1)这两个问题的原因是目标机器上缺少VC8相关的运行库或者版本不匹配,最简单的解决方案就是把VC安装目录下vcredist_x86目录下的vcredist_x86.exe在目标机器上运行一把,把库安装上去就解决了。
2)是缺少了dll文件所导致的这个错误,只要把以下dll复制到执行程序exe的当前目录下面,就可以了,这几个dll分别是:(msvcm80.dll,msvcp80.dll,msvcr80.dll,Microsoft.VC80.CRT.manifest)或(msvcm80d.dll、msvcp80d.dll、msvcr80d.dll、Microsoft.VC80.DebugCRT.manifest)
3)VC++2005对dll的版本要求非常严格,对于用VC++2005编写的程序和动态链接库,Release版本的程序必须调用Release版本的dll,Debug版本的程序必须调用Debug版本的dll,否则就可能出现这个问题。
用VC2005编译的程序,编译时没有任何错误,但是运行时就是提示“应用程序正常初始化失败”:
1)VC2003、VC2005、VC2008及其后续版本,对底层最基本的CRT、MFC、ATL库都进行了重构,为了避免不同版本的库引起冲突,重构后的库文件一般放在 C://windows/WinSxS 文件夹中,并用特定的文件夹/文件名称进行标识;
2)与VC6不同, VC2003、VC2005、VC2008及其后续版本,引入了manifest清单的概念,即应用程序编译后会同时生成对应的.manifest文件,并将该.manifest文件作为资源编译到dll或者exe中去。.manifest文件实际上是一个XML格式的文本文件,里面记录了dll或exe中要引用的CRT、MFC、ATL库的版本和名称。VC6编译的应用程序对CRT、MFC、ATL的dll都是直接调用,而VC2003、VC2005、VC2008编译的程序都是先查询编译到资源中的manifest中的记录,然后按照记录提供的版本和名称去搜寻对应的CRT、MFC、ATL库以及随库发布的.manifest文件,搜寻的路径包括当前目录、C://windows/WinSxS 等等,如果没有找到对应的库文件,则提示“应用程序正常初始化失败”;
3)用文本编辑器打开exe或dll对应的.manifest文件,查看它引用的CRT、MFC、ATL库的版本;或者,用UltraEdit直接打开exe或者dll,从资源区中找到编译进去的.manifest信息,找到它引用的CRT、MFC、ATL库的版本;或者,运行程序,当程序弹出“应用程序正常初始化失败”对话框时,打开事件查看器,可以看到出错的原因是因为缺少了某某版本的CRT、MFC、ATL库,这个库的版本信息一般类似于“Microsoft.VC80.DebugCRT”,之后到C://windows/WinSxS 或者VC200X的安装文件夹中搜索包含这个字符串的文件夹和文件,将搜索到的dll和.manifest文件都拷贝到应用程序所在的文件夹中,其中,.manifest文件必须重命名(例如重命名为Microsoft.VC80.DebugCRT),这样应用程序就可以正常运行了;
关于生成清单:
VS2005在生成可执行文件时使用了一种新的技术,该技术生成的可执行文件会伴随生成一个清单文件(manifest file)(.manifest后缀文件)(其本质上是XML文档,你可以用文本编辑器打开看看),并在链接完成后将该清单文件嵌入到exe文件中(默认情况下)。而在FAT32文件系统中,在处理清单文件阶段,当增量链接时不能完成清单文件的更新(默认情况下),于是造成清单文件嵌入失败,从而使该exe文件运行时没有相应的清单文件而运行失败并提示如上错误。
解决方案很多,列举如下:
1)由于这是在链接动态运行库出现的问题,所以你可以选择代码生成的连接方式为/MTd而非/MDd,不用这些DLL文件从而避免问题的出现。该方法有一个很显然的缺点:适用范围有限,不推荐该方法。
2)既然跟FAT32系统有关,那么我们可以选择在NTFS文件系统中开发从而避免该问题,此方法同上,也是采用的回避问题的方式,不提倡。
3)该方法仍与FAT32有关:在项目的“属性|配置属性|清单工具|常规”中的“使用FAT32解决办法”选择“是”(默认为“否”),重新生成项目即可解决问题。该方法是唯一真正针对问题所在而提出的解决方法,使清单工具可以正确更新。(此方法是官方解决方法,也比较方便,推荐)
4)既然问题是在更新嵌入的清单文件时发生的,由于FAT32的原因而未能更新嵌入的清单文件,于是我们有如下两种解决方法:
1、不启用增量链接。在项目的“属性|配置属性|链接器|常规”中的“启用增量链接”选择“否”。此方法阻断了问题产生的源头,其每次生成exe文件时都直接嵌入清单文件,而不是默认的根据时戳而决定是否更新清单文件。
2、不嵌入清单文件。在项目的“属性|配置属性|清单工具|输入和输出”中的“嵌入清单”选择“否”,从而在生成exe文件时附随生成一个清单文件(默认情况下,其文件名为exe文件的全名加上“.manifest”),避免了嵌入清单文件可能失败的问题。在程序运行时,会用到该清单文件。显然,这种方式使可执行程序产生了更多的外部依赖,不推荐。