开发者社区> 技术小美> 正文

VC编写的程序不能在其他机器上运行的解决方案

简介:
+关注继续查看

有的时候,你在Visual C++上面经过好几个月的辛勤努力,终于将程序编写完成并且测试完毕,然而当你试图在客户的发布机上运行刚写好的程序时,有可能会碰到类似下面的错误,操作系统告诉你“由于应用程序配置不正确,应用程序未能启动。重新安装应用程序可能会纠正这个问题”:

一般情况下,这个问题都是由于程序不能找到所需要的C运行库(CRT)而引起的。

 

Windows XP SP2以后,Windows引入了Side-by-Side执行的概念,这个概念本来是.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升级到20082008MFC库是9.0版本的,这个时候你的操作系统里面安装了两个版本的MFC,分别是8.09.0

3.         你在Visual Studio 2008编写了另外一个C++程序BB依赖与MFC 9.0

4.         如果你运行程序A的话,操作系统会将MFC 8.0加载到A的进程里面。

5.         如果你这时同时运行程序B,操作系统会将MFC 9.0加载到B的进程里面。这就是Side-by-side的执行概念。

 

操作系统之所以能够这样做,是因为它在加载程序AB之前,除了查看PE格式里面AB所依赖的Dll信息,都会查看ABmanifest文件。Manifest文件保存了Windows可执行文件(包括exedll文件)要运行起来的环境设置信息,文件名一般是可执行文件的文件全名加上.manifest。例如notepad.exemanifest文件就应该是notepad.exe.manifest。例外有的程序将manifest文件直接嵌入到可执行文件的资源里面了,这也就是为什么有的时候你看不到程序的manifest文件的原因。通常来说,一个manifest文件的内容如下(test.exe.manifest文件):

<?xml version='1.0encoding='UTF-8standalone='yes'?>

<assembly xmlns='urn:schemas-microsoft-com:asm.v1manifestVersion='1.0'>

 <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">

    <security>

      <requestedPrivileges>

        <requestedExecutionLevel level='asInvokeruiAccess='false' />

      </requestedPrivileges>

    </security>

 </trustInfo>

 <dependency>

    <dependentAssembly>

      <assemblyIdentity type='win32name='Microsoft.VC90.DebugCRTversion='9.0.21022.8'

                        processorArchitecture='x86publicKeyToken='1fc8b3b9a1e18e3b' />

    </dependentAssembly>

 </dependency>

</assembly>

上面的例子里面,就说明这个程序依赖于CRT 9.0,而且是调试版的,CPU架构是32位的CPU。对于将manifest文件嵌入到资源文件的程序我们也有办法看到manifest的信息。

1.         一种是使用mt.exeVisual Studio自带的manifest处理程序):

mt -inputresource:test.exe;#1 /out:test.manifest

2.         另外一种是使用dumpbin程序将整个exe的内容打印到一个文件,然后用文本编辑器打开,搜索Assem字符串样式就能找到manifest信息:

 

解决方案

知道了程序依赖于具体哪一个dll以后,你可以将所依赖的dll拷贝到程序的安装文件夹里面,以CRT库绑定失败为例,介绍解决步骤:

1.         从上例中我们知道程序依赖的Microsoft.VC90.DebugCRT库,版本号是9.0.21022.8,需要32位机器版本的CRT。这个依赖项一般是因为你的程序是调试版,所以Visual Studio在编译的时候,将调试版的CRT加入程序的依赖项。

2.         Visual Studio的安装文件夹里面将D:"Program Files"Microsoft Visual Studio 9.0"VC"redist"Debug_NonRedist"x86中的Microsoft.VC90.DebugCRT整个文件夹拷贝到应用程序所在的文件夹里面,注意:

a)         如果你的程序依赖的是32位的CRT,则要拷贝x86文件夹里面的Microsoft.VC90.DebugCRT文件夹,如果是先x64程序,则要拷贝x64文件夹里面。

b)         你需要确定Microsoft.VC90.DebugCRT文件夹里面的Microsoft.VC90.DebugCRT.manifest文件里面保存的版本信息而你程序依赖的版本信息匹配,Microsoft.VC90.DebugCRT.manifest里面的版本信息大版本号一定要一致,小版本号一定要等于或者大于你程序依赖的CRT的小版本号。比如上例中,我们的程序是依赖于CRT 9.0.21022.8,而我们的Microsoft.VC90.DebugCRT.manifest的版本是9.0.30729.1,这样是可以的;而8.0.30729.1就会有问题。如果大版本号一样,小版本号不一致的话,一个比较简单的方案就是修改程序的manifest文件,使其互相匹配就可以了。

3.         如果你的程序不是依赖调试版本的CRT,而是release版本的CRT,直接去微软的官方网站下载一个crt redist包安装上就可以了。


本文转自 donjuan 博客园博客,原文链接: http://www.cnblogs.com/killmyday/archive/2009/02/20/1394596.html  ,如需转载请自行联系原作者

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
无影云桌面和服务器有什么区别?阿里云无影电脑有什么优势?
阿里云推出无影云桌面,云桌面是一种安全高效的云上桌面服务,一般用于企业办公。云桌面支持快速便捷的桌面环境创建、部署、统一管控与运维。企业选择云桌面无需前期传统硬件投资,云桌面可以快速构建安全、高性能、低成本的企业桌面办公体系。云桌面和传统PC、VDI之间的区别:
17 0
飞天加速计划初体验
最近因需要使用云服务器来学习,老师让我们用这个阿里云类进行相关的学习,让我们先进行免费的使用进行学习,慢慢了解,毕竟对于首次接触的事物都是了解为主不会投入大量资金。阿里云平台有详细的教程,让初学者能十分轻松的进行学习。飞天加速计划是个好想法,可以让我们这些学生进行学习,制作出自己的网站。让我在暑假对计算机有了浓厚的兴趣,于是在阿里云我选择了飞天加速计划,学习大数据和服务器啥的,让自己get到更多的知识~
14 0
我的ECS使用体验报告
学生用户初次使用阿里云服务器的体验报告
6 0
Swift5.0 - day5-继承、初始化、可选链、协议(上)
Swift5.0 - day5-继承、初始化、可选链、协议(上)
5 0
保姆级教程:WebStorm创建VUE项目
保姆级教程:WebStorm创建VUE项目
8 0
Swift5.0 - day8-内存访问冲突、指针
Swift5.0 - day8-内存访问冲突、指针
5 0
今天是 Java 诞生日,Java 27 岁了!
Java语言最早被称为Oak,它是为了实现嵌入式的消费类电子产品应用而产生的,它的作者是James Gosling.Ed Frank, Patrick Naughton, Jonathan Payne, Chris Warth在随后的几年时间中为Java语言加入了大量的特性,并把Java语言的目标做了一个重新的定位,定位于适合Internet的语言。 Java语言是一种多用途的语言、并发的语言、以类为基础,面向对象的语言。它的设计尽可能的做到和操作系统是无关的,也就是Java所宣传的那句话:"一次编写,到处运行。
9 0
Swift5.0 - day12 - 面向协议编程
Swift5.0 - day12 - 面向协议编程
5 0
Python 脚本一个要注意的点
Python 脚本一个要注意的点
2 0
+关注
6902
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
OceanBase 入门到实战教程
立即下载
阿里云图数据库GDB,加速开启“图智”未来.ppt
立即下载
实时数仓Hologres技术实战一本通2.0版(下)
立即下载