开发的某些程序在其他机器运行提示“由于应用程序配.doc
《开发的某些程序在其他机器运行提示“由于应用程序配.doc》由会员分享,可在线阅读,更多相关《开发的某些程序在其他机器运行提示“由于应用程序配.doc(9页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、转自: VS2008环境下开发的某些程序在其他机器运行提示“由于应用程序配置不正确,应用程序未能启动”的问题(IIS)比较全的有关vs2008部署问题集(1):比较全的有关vs2008部署问题集(2):/原文地址:VC9编译的程序在没有装过VC9(确切的说是.Net Framework3.5)的机器上运行时,如果提示“由于应用程序配置不正确,应用程序未能启动。重新安装应用程序可能会纠正这个问题。”这个错误,那么就说明该程序动态链接了VC9的运行时库,(如果还用到了MFC,那么可能动态链接了VC9的MFC库,同理还有ATL库),以及缺少对应的 manifest文件,程序在目标机器上没有找到这些库
2、和配置文件,因此导致了这个错误。出现这种情况的VC9编译器可能存在3个版本,接下来分别阐明:1、没有打过任何补丁的VS2008该版本对应的CRT/MFC/ATL库的版本号为9.0.21022.8,这个版本号在后面会用到。这个版本的程序部署比较简单,直接把VC安装目录下的redist目录(C:Program FilesMicrosoft Visual Studio 9.0VCredist)中需要的库以及对应的manifest文件拷贝到执行程序同目录下,这样程序到任何机器上都能够正常运行了。2、打过SP1补丁的VS2008打过该补丁后,系统中存在着两个版本的CRT/MFC/ATL库,版本号分别为9
3、.0.21022.8和9.0.30729.1,这导致了 manifest文件中记录的版本号和实际库的版本号不一致(程序要求它们的版本号一致才能运行)。这个版本的程序部署需要两个步骤,首先要使 manifest文件中依赖项的版本号与实际库的版本号一致,均为9.0.30729.1,方法是在工程设置中增加一个宏定义 _BIND_TO_CURRENT_VCLIBS_VERSION,该宏定义于C:Program FilesMicrosoft Visual Studio 9.0VCincludecrtassem.h文件中,然后重新编译程序。接下来还是将VC安装目录下的redist目录(C:Program
4、FilesMicrosoft Visual Studio 9.0VCredist)中需要的库以及对应的manifest文件拷贝到执行程序同目录下,然后修改manifest文件中依赖项的版本号为 9.0.21022.8,这样使得程序误以为该目录下库的版本号为9.0.21022.8(实际上是9.0.30729.1版本),这样程序到任何机器上都能够正常运行了。3、打过SP1补丁与SP1 ATL 安全更新 (KB973675)的VS2008这是最新的更新。在SP1补丁之后,微软又于近日发布了一个用于智能设备的 Microsoft Visual Studio 2008 Service Pack 1 AT
5、L 安全更新 (KB973675),该补丁又将CRT/MFC/ATL库的版本号升级,为9.0.30729.4148,这次升级比较好,manifest文件与库的版本号一致了,不像 SP1一样升级的不彻底。这样只需要在工程设置中增加一个宏定义_BIND_TO_CURRENT_VCLIBS_VERSION,接下来重新编译程序,然后直接把VC安装目录下的redist目录中需要的库以及对应的manifest文件拷贝到执行程序同目录下,这样程序到任何机器上都能够正常运行了。顺便提一下,如果不想在发布程序时带上这些库和manifest文件(如果没有必要的话),那么可以采用静态编译CRT和MFC,然后把man
6、ifest文件添加到资源中,这样编译出的程序只要一个exe就可以在任何机器上直接运行了。参考文章:1、“应用程序配置不正确,程序无法启动”的解决方法资料收集:有的时候,你在Visual C+上面经过好几个月的辛勤努力,终于将程序编写完成并且测试完毕,然而当你试图在客户的发布机上运行刚写好的程序时,有可能会碰到类似下面的错误,操作系统告诉你“由于应用程序配置不正确,应用程序未能启动。重新安装应用程序可能会纠正这个问题”:一般情况下,这个问题都是由于程序不能找到所需要的C运行库(CRT)而引起的。在Windows XP SP2以后,Windows引入了Side-by-Side执行的概念,这个概念本
7、来是.NET提出来的,但是Windows后来将这个概念集成到操作系统层面上来了。大家都应该知道Dll Hell的问题,为了解决Dll Hell的问题,Side-By-Side提出不同版本的dll文件可以同时存在于同一个系统里面,而且依赖于不同版本dll的应用程序在运行的时候可以使用到它当初被编译生成的dll。前面的话,有点绕,举个例子:1. 假定你编写了一个C+程序A,是使用MFC 8.0(这个版本是随着Visual Studio 2005)发布的。2. 之后你的机器升级了Visual Studio的版本,从2005升级到2008,2008的MFC库是9.0版本的,这个时候你的操作系统里面安装
8、了两个版本的MFC,分别是8.0和9.0。3. 你在Visual Studio 2008编写了另外一个C+程序B,B依赖与MFC 9.0。4. 如果你运行程序A的话,操作系统会将MFC 8.0加载到A的进程里面。5. 如果你这时同时运行程序B,操作系统会将MFC 9.0加载到B的进程里面。这就是Side-by-side的执行概念。操作系统之所以能够这样做,是因为它在加载程序A和B之前,除了查看PE格式里面A和B所依赖的Dll信息,都会查看A和B的manifest文件。Manifest文件保存了Windows可执行文件(包括exe和dll文件)要运行起来的环境设置信息,文件名一般是可执行文件的文
9、件全名加上.manifest。例如notepad.exe的manifest文件就应该是notepad.exe.manifest。例外有的程序将 manifest文件直接嵌入到可执行文件的资源里面了,这也就是为什么有的时候你看不到程序的manifest文件的原因。通常来说,一个 manifest文件的内容如下(test.exe.manifest文件): 上面的例子里面,就说明这个程序依赖于CRT 9.0,而且是调试版的,CPU架构是32位的CPU。对于将manifest文件嵌入到资源文件的程序我们也有办法看到manifest的信息。1. 一种是使用mt.exe(Visual Studio自带的m
10、anifest处理程序):mt -inputresource:test.exe;#1 /out:test.manifest2. 另外一种是使用dumpbin程序将整个exe的内容打印到一个文件,然后用文本编辑器打开,搜索Assem字符串样式就能找到manifest信息:解决方案知道了程序依赖于具体哪一个dll以后,你可以将所依赖的dll拷贝到程序的安装文件夹里面,以CRT库绑定失败为例,介绍解决步骤:1. 从上例中我们知道程序依赖的Microsoft.VC90.DebugCRT库,版本号是9.0.21022.8,需要32位机器版本的CRT。这个依赖项一般是因为你的程序是调试版,所以Visual
11、 Studio在编译的时候,将调试版的CRT加入程序的依赖项。2. 从Visual Studio的安装文件夹里面将D:”Program Files”Microsoft Visual Studio 9.0VC”redist”Debug_NonRedist”x86中的Microsoft.VC90.DebugCRT整个文件夹拷贝到应用程序所在的文件夹里面,注意:a) 如果你的程序依赖的是32位的CRT,则要拷贝x86文件夹里面的Microsoft.VC90.DebugCRT文件夹,如果是先x64程序,则要拷贝x64文件夹里面。b) 你需要确定Microsoft.VC90.DebugCRT文件夹里面的
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 开发 某些 程序 其他 机器 运行 提示 由于 应用程序
限制150内