VS2008编译的程序在某些机器上运行提示“由于应用程序配置不正确, VC9编译的程序在没有装过VC9(确切的说是.Net Framew ork3.5)的机器上运行时,如果提示“由于应用程序配置不正确,应用程序未能启动。重新安装应用程序可能会纠正这个问题。”这个错误,那么就说明该程序动态链接了VC9的运行时库,(如果还用到了MFC,那么可能动态链接了VC9的MFC库,同理还有AT L 库),以及缺少对应的mani fest文件,程序在目标机器上没有到这些库和配 置文件,因此导致了这个错误。出现这种情况的VC9编译器可能存在3个版本,接下来分别阐明:
1、没有打过任何补丁的VS2008
该版本对应的CRT/MFC/ATL库的版本号为9.0.21022.8,这个版本号在后面会用到。这个版本的程序部署比较简单,直接把VC安装目录下的redis t目录(C:\Progra m Files\Micros oft Visual Studio 9.0\VC\redist)中需要的库以及对应的m anife st文件拷贝到执行程序同目录下,这样程序到任何机器上都能 够正常运行了。
2、打过SP1补丁的VS2008
打过该补丁后,系统中存在着两个版本的CRT/MFC/ATL库,版本号分别为9.0.21022.8和9.0.30729.1,这导致了ma nifes t文件中记录的版本号和实际库的版本号不一致(程序要求它们的版本号一致才能运行)。这个版本的程序部署需要两个步骤,首先要使ma nifes t文件中依赖项的版本号与实际库的版本号一致,均为9.0.30729.1,方法是在工程设置中增加一个宏定义
_BIND_TO_C URREN T_VCL IBS_V ERSIO N,该宏定义于C:\Progra m Files\Micros oft Visual Studio 9.0\VC\includ e\crtass em.件中,然后重新编译程序。接下来还是将VC安装目录下的re dist目录(C:\Progra m Files\Micros oft Visual Studio 9.0\VC\redist)中需要的库以及对应的m anife st文件拷贝到执行程序
同目录下,然后修改ma nifes t文件中依赖项的版本号为9.0.21022.8,这样使
得程序误以为该目录下库的版本号为9.0.21022.8(实际上是9.0.30729.1版本),这样程序到任何机器上都能够正常运行了。
适用性
3、打过SP1补丁与SP1 ATL 安全更新 (KB973675)的VS2008
这是最新的更新。在SP1补丁之后,微软又于近日发布了一个用于智能设备的 Micros oft Visual Studio2008 Servic e Pack 1 ATL 安全更新 (KB973675),该补丁又将C RT/MFC/ATL库的版本号升级,
为9.0.30729.4148,这次升级比较好,manife st文件与库的版本号一致了,不像SP1一样升级的不彻底。这样只需要在工程设置中增加一个宏定义_BI ND_TO_CURR ENT_V CLIBS_VERS ION,接下来重新编
译程序,然后直接把V C安装目录下的red ist目录中需要的库以及对应的
manif est文件拷贝到执行程序同目录下,这样程序到任何机器上都能够正常运行了。
顺便提一下,如果不想在发布程序时带上这些库和manif est文件(如果没有必要的话),那么可以采用静态编译C RT和MF C,然后把man ifest文件添加到资源中,这样编译出的程序只要一个exe就可以在任何机器上直接运行了。
参考文章:
淮南市公安局局长
1、“应用程序配置不正确,程序无法启动”的解决方法资料收集:
有的时候,你在Visu al C++上面经过好几个月的辛勤努力,终于将程序编写完成并且测试完毕,然而当你试图在客户的发布机上运行刚写好的程序时,有可能会碰到类似下面的错误,操作系统告诉你“由于应用程序配置不正确,应用程序未能启动。重新安装应用程序可能会纠正这个问题”.
一般情况下,这个问题都是由于程序不能到所需要的C运行库(CRT)而引起的。
ibm x22
在Windo ws XP SP2以后,Window s引入了S ide-by-Side执行的概念,这个概念本来是.NET提出来的,但是Wind ows后来将这个概念集成到操作系统层面上来了。大家都应该知道Dll Hell的问题,为了解决Dll Hell的问题,Side-By-Side 提出不同版本的dll文件可以同时存在于同一个系统里面,而且依赖于不同版本dl l的应用程序在运行的时候可以使用到它当初被编译生成的dll。前面的话,有点绕,举个例子:
1. 假定你编写了一个C++程序A,是使用MFC8.0(这个版本是随着Visu al Studio 2005)发布的。
2. 之后你的机器升级了Vi sualStudio的版本,从2005升级到2008,2008的M FC库是9.0版本的,这个时候你的操作系统里面安装了两个版本的M FC,分别是8.0和9.0。
3. 你在Visu al Studio 2008编写了另外一个C++程序B,B依赖与MF C 9.0。
4. 如果你运行程序A的话,操作系统会将MFC 8.0加载到A的进程里面。
5. 如果你这时同时运行程序B,操作系统会将MFC 9.0加载到B的进程里面。这就是Sid e-by-side的执行概念。
操作系统之所以能够这样做,是因为它在加载程序A和B之前,除了查看PE 格式里面A和B所依赖的Dll
石龙二中
信息,都会查看A和B的man ifest文件。Manife st 文件保存了Win dows可执行文件(包括exe和dll文件)要运行起来的环境设置信息,文件名一般是可执行文件的文件全名加上.manife st。例如not的ma nifes t文件就应该是not epad.exe.manife st。例外有的程序将mani fest文件直接嵌入到可执行文件的资源里面了,这也就是为什么有的时候你看不到程序的man ifest文件的原因。通常来说,一个mani fest文件的内容如下
(anife st文件):
上面的例子里面,就说明这个程序依赖于C RT 9.0,而且是调试版的,CPU
架构是32位的C PU。对于将man ifest文件嵌入到资源文件的程序我们也有办法
看到manif est的信息。
1. 一种是使用(Visual Studio自带的ma nifes t处理程序):
mt -inputr esour ;#1 /out:test.manife st
2. 另外一种是使用dump bin程序将整个ex e的内容打印到一个文件,然后用文本编辑器打开,搜索Asse m字符串样式就能到manif est信息:
解决方案
知道了程序依赖于具体哪一个dll以后,你可以将所依赖的dll拷贝到程序的安装文件夹里面,以CRT库绑定失败为例,介绍解决步骤:
1.从上例中我们知道程序依赖的Mic rosof t.VC90.DebugC RT库,版本号是
9.0.21022.8,需要32位机器版本的C RT。这个依赖项一般是因为你的程序是调
试版,所以Visu al Studio在编译的时候,将调试版的C RT加入程序的依赖项。
2.从Visua l Studio的安装文件夹里面将D:"Progra m Files"Micros oft Visual Studio 9.0"VC"redist"Debug_NonRe dist"x86中
的M icros oft.VC90.DebugC RT整个文件夹拷贝到应用程序所在的文件夹里面,注意:
a)如果你的程序依赖的是32位的CR T,则要拷贝x86文件夹里面的
Mic rosof t.VC90.DebugC RT文件夹,如果是先x64程序,则要拷贝x64文件夹里面。
b)你需要确定M icros oft.VC90.DebugC RT文件夹里面的
Mi croso ft.VC90.DebugC RT.manife st文件里面保存的版本信息而你程序依赖的版本信息匹配,Micros oft.VC90.DebugC RT.manife st里面的版本信息大版本号一定要一致,小版本号一定要等于或者大于你程序依赖的CR T的小版本号。比如上例中,我们的程序是依赖于CR T 9.0.21022.8,而我们的
Mi croso ft.VC90.DebugC RT.manife st的版本是9.0.30729.1,这样是可以的;而8.0.30729.1就会有问题。如果大版本号一样,小版本号不一致的话,一个比较简单的方案就是修改程序的manif est文件,使其互相匹配就可以了。
3.如果你的程序不是依赖调试版本的C RT,而是rele ase版本的CRT,直接去微软的下载一个cr t redist包安装上就可以了。
附:解决方案参考:
方案一:
观察物体教学设计方法一:
在C:\Progra m Files\Micros oft Visual Studio 8\VC\redi
st\Debug_NonRe dist\x86\Micros oft.VC80.DebugC RT 下到了下列文件:
msvcm80d.dll
msvcp80d.dll
msvcr80d.dll
产业结构调整指导目录 2011年本
Micros oft.VC80.DebugC RT.manife st
把这几个文件拷贝到目标机器上,与运行程序同一文件夹或放到sys tem32下,就可以运行那个程序了。
其他rele ase版,MFC程序什么的都是拷redis t下相应文件夹下的文件就可以了,文件夹后都有标识!
方法二:
修改编译选项,将/MD或/MDd 改为 /MT或/MTd,这样就实现了对VC运行时库的静态链接,在运行时就不再需要VC的dll了。