“应用程序配置不正确,程序无法启动”详细举例

2023-11-01

参考资料: 应用程序配置不正确,程序无法启动 的解决方法资料收集

内容我就不copy了,大家可以自己去看,总来说产生这个问题的原因可以归结如下:

vc2005/vc2008采用了新的程序部署技术(manifest清单文件),manifest清单文件实际上类似于我们常用的makefile文件,它定义了程序运行的依赖关系(程序运行所需要的dll库的名称、版本等)。

程序运行,首先根据manifest清单文件(这个文件可以嵌入到exe或dll中,或者单独生成外部文件,可以通过vc2005/vc2008的编译选项控制:工程“属性”->“配置属性”->“清单工具”->“输入输出”->“嵌入清单文件”,选择“是”或“否”来控制)来查找程序运行需要的dll库的名称、版本等,如果所在的系统中没有程序运行所需要的dll库和相应的manifest清单文件,则弹出“应用程序配置不正确,程序无法启动对话框。

另外要注意,由于vc2005/vc2008与.net集成,导致出现一个新的概念:在.net中,将exe、dll都看成“程序集(assemble)”,每个程序集(assemble)都附带有一个manifest清单文件,因此使得vc2005/vc2008的CRT(C 运行时库)、MFC、ATL等dll库都附带有一个manifest清单文件。

归根结底是由于老版本的系统没有我们开发的程序运行所需要的基本运行时库(2k、xp系统只有vc6的一些dll库,而没有vc2005、vc2008所需要的dll库以及相应的manifest清单文件,而在vista系统或者即将到来的windows 7系统上则包含有vc2005、vc2008的dll库和manifest清单文件)

ps:上面的那段话说的有点幼稚和简单了,这里涉及到很多的问题:程序的升级更新、vs的补丁、库的版本问题等等,不是简单的拷贝、粘贴就能解决的。。。

举个例子:(在XP SP3系统下)

使用vc2008 express sp1版(没有mfc、atl),新建一个“HelloWorld”的“win32控制台应用程序”工程,在release下编译,此时默认的编译选项:(在这里我们只关注与我们的问题相关的几个选项)

1、工程“属性”->“配置属性”->“c/c++”->“代码生成”->“运行库”

默认选项为/MD(release)、/MDd(debug),对这几个编译选项不清楚的可以参见: VC运行库版本不同导致链接.LIB静态库时发生重复定义问题的一个案例分析和总结

2、工程“属性”->“配置属性”->“清单工具”->“输入输出”->“嵌入清单文件”

默认选项为“是”(表示将manifest清单文件嵌入到程序中);当然,我们也可以选择“否”,从而单独生成一个manifest清单文件,不过这会增加不必要的依赖项,因此不建议选择“否”。

编译->链接之后在“ HelloWorld ”工程的release或debug目录下,我们能够看到一个HelloWorld.exe.intermediate.manifest清单文件(根据编译选项,见上,vc2008将manifest清单文件嵌入到了exe程序中,HelloWorld.exe.intermediate.manifest清单文件是一个临时文件,但它的内容与嵌入到exe程序的manifest文件是一样的),用文本编辑器打开该文件(用“记事本”也行,不过格式太乱,看不清楚内容,推荐使用vim或其它的文本编辑器查看),大致内容如下:

ps:在网上看到另外的一个方法,用记事本打开exe或dll程序,查看嵌入到exe或dll中的manifest清单文件,方法:“打开记事本,然后将exe或dll拖入到记事本中,当然了,肯定会出现大段的乱码,没关系,直接往后看,就能发现类似于下面的内容的部分

XML语言HelloWorld.exe.intermediate.manifest

01 <?xml version='1.0' encoding='UTF-8' standalone='yes'?>
02 <assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'>
03 <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
04      <security>
05        <requestedPrivileges>
06          <requestedExecutionLevel level='asInvoker' uiAccess='false' />
07        </requestedPrivileges>
08      </security>
09 </trustInfo>
10 <dependency>
11      <dependentAssembly>
12        <assemblyIdentity type='win32' name='Microsoft.VC90.CRT' version='9.0.21022.8' processorArchitecture='x86' publicKeyToken='1fc8b3b9a1e18e3b' />
13      </dependentAssembly>
14 </dependency>
15 </assembly>

我们重点查看红色部分,这说明编译后的exe程序依赖于vc90(也即vc2008)的CRT(C运行时库),版本9.0.210022.8(这是由于使用/MD选项,程序动态的依赖于CRT,如果使用/MT选项,则会将CRT静态链接到程序中,当然,这会使程序的尺寸急剧的增长,大概有10倍的大小差距)

当exe程序执行时,它会根据嵌入的manifest文件查找相应的依赖项,在这个HelloWorld.exe程序中,它依赖于vc90 CRT,因此它会在“C:\WINDOWS\WinSxS和“当前目录下查找相应的dll库以及manifest文件,(这里指的是xp系统,不考虑vista系统,具体的参见:程序集搜索顺序)

在我的机器上有2个版本的vc90 CRT(由于安装了vc2008 express sp1)

vc90 CRT的dll库位于9.0.21022.8版本)“C:\WINDOWS\WinSxS\x86_Microsoft.VC90.CRT_1fc8b3b9a1e18e3b_9.0.21022.8_x-ww_d08d0375”

相应的manifest文件则位于“C:\WINDOWS\WinSxS\Manifests\x86_Microsoft.VC90.CRT_1fc8b3b9a1e18e3b_9.0.21022.8_x-ww_d08d0375.manifest”

vc90 CRT的dll库位于9.0.30729版本)“C:\WINDOWS\WinSxS\x86_Microsoft.VC90.CRT_1fc8b3b9a1e18e3b_9.0.30729.1_x-ww_6f74963e”

相应的manifest文件则位于“C:\WINDOWS\WinSxS\Manifests\x86_Microsoft.VC90.CRT_1fc8b3b9a1e18e3b_9.0.30729.1_x-ww_6f74963e.manifest”

在这里我们就有一个疑问了,我们的开发环境是vc2008 express sp1,那么我们的程序链接的CRT版本应该是9.0.30729版本的啊?这个不是我瞎说的,大家可以用dependency walker来查看程序实际链接的DLL版本),为什么在manifest文件中依赖的CRT却是9.0.21022.8版本的?这里就涉及到一个新的名词“policy ",操作系统会根据C:\WINDOWS\WinSxS\Policies\x86_policy.9.0.Microsoft.VC90.CRT_1fc8b3b9a1e18e3b_x-ww_b7353f75\9.0.30729.1.policy文件的内容,进行dll版本的跳转(重点看深蓝斜体字部分)从而选择了9.0.30729版本vc90 CRT (这个所谓的“policy跳转”是道听途说来的,具体的英文资料藏在microsoft的什么地方我就不得而知了。里面夹带了一些我自己的主观猜测,不然的话,没有办法解释manifest版本号9.0.21022.8是,而实际链接的dll的版本号却是9.0.30729

XML语言9.0.30729.1.policy
01  <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
02  <!-- Copyright (c) Microsoft Corporation. All rights reserved. -->
03  <assembly  xmlns= "urn:schemas-microsoft-com:asm.v1"  manifestVersion= "1.0" >
04      <assemblyIdentity  type= "win32-policy"  name= "policy.9.0.Microsoft.VC90.CRT"  version= "9.0.30729.1"  processorArchitecture= "x86"  publicKeyToken= "1fc8b3b9a1e18e3b" />
05      <dependency>
06          <dependentAssembly>
07              <assemblyIdentity  type= "win32"  name= "Microsoft.VC90.CRT"  processorArchitecture= "x86"  publicKeyToken= "1fc8b3b9a1e18e3b" />
08             <bindingRedirect oldVersion="9.0.20718.0-9.0.21022.8" newVersion="9.0.30729.1"/>
09             <bindingRedirect oldVersion="9.0.30201.0-9.0.30729.1" newVersion="9.0.30729.1"/>

10          </dependentAssembly>
11      </dependency>
12  </assembly>

如果我们将这个HelloWorld.exe拷贝到其它的机器上(没有安装vc2008 sp1Microsoft Visual C++ 2008 SP1 Redistributable Package (x86)),则程序因为没能找到vc90 CRT,而不能运行,弹出“应用程序配置不正确,程序无法启动对话框。

根据参考资料的文章中的内容,对于release版程序,有一个简单的办法就是安装vcredist_x86.exe,文件大小4M左右,自动安装在“C:\WINDOWS\WinSxS目录下,包含了CRT、MFC、ATL等库的dll和manifest清单文件;整个安装时间不到1分钟。

如果机器上安装了vc2005/vc2008,则会自动的安装vcredist_x86.exe程序,安装后在控制面板”->“添加删除程序”中有一项“Microsoft Visual c++ 2008 Redistributable - x86 9.0.3.729(我安装的是Microsoft Visual C++ 2008 SP1 Redistributable Package (x86) 版本)

注意:要根据编译器版本以及vc2005/vc2008是否安装了sp1补丁进行选择对应的vcredist.exe版本



引:“应用程序配置不正确,程序无法启动”详细举例(1)(vc2008 sp1)

上述的解决办法我称之为共享程序集部署方法,同样的我们也可以采用私有程序集的部署方式来发布程序

Helloworld例子的私有程序集的部署方法:(针对release版本,仍然是采用上面的例子

,采用参考资料中提到的第2中私有程序集部署方法:将Microsoft.VC90.CRT目录下的manifest文件的版本号修改为9.0.21022.8

1、将编译后的程序拷贝到一个目录下,假定为d:\helloworld

2、将vc安装目录下的redist\x86目录下的Microsoft.VC90.CRT目录拷贝到d:\helloworld(假定vs安装在C:\Program Files\Microsoft Visual Studio 9.0,则vc安装目录为C:\Program Files\Microsoft Visual Studio 9.0\VC)

3、将Microsoft.VC90.CRT目录下的manifest文件的版本号修改为9.0.21022.8用记事本打开修改

最终发布程序的目录结构

D:\helloworld

      |--helloworld.exe

      |--Microsoft.VC90.CRT

                     |--Microsoft.VC90.CRT.manifest

                    |--msvcm90.dll

                     |--msvcp90.dll

                    |--msvcr90.dll

这个时候,程序的manifest文件(已经内嵌到exe中了)依赖的vc90 CRT的版本号和Microsoft.VC90.CRT.manifest文件的版本号对应一致,都是9.0.21022.8但是要注意的是,我们的helloworld程序实际上依赖的vc90 CRT版本是9.0.30729版本这里只是采用了一种欺骗的方法,因为我们编译时链接的CRT的版本是9.0.30729版本)


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

“应用程序配置不正确,程序无法启动”详细举例 的相关文章

随机推荐

  • Python每日一练第3天——按要求实现程序功能

    按要求实现程序功能 每日一练 做题 1 定义一个函数prime判断某个整数是否为素数 2 然后从键盘输入一行字符串 将其中的连续数字依次提取出来形成一个列表 例如 字符串 ab12cd34fg67 按要求提取后形成列表 12 34 67 3
  • 突如其来的久违的WPF学习(3)

    如何设置C 中queue为固定长度 已知queue的存储规则为先进先出 最终的解决方法为设计一个固定长度的队列类 然后接口设置为数据长度 目前唯一的问题是这样就好像不知道怎么不定义队列的内容了 之所以需要重新包装是因为queue自带的队列长
  • OpenAI 发布 GPT-4,有哪些技术上的优化或突破?

    GPT 4 这是 OpenAI 努力扩展深度学习的里程碑 GPT 4 是一个大型多模态模型 接受图像和文本输入 发出文本输出 虽然在许多现实世界场景中的能力不如人类 但在各种专业和学术基准上表现出人类水平的表现 例如 它通过模拟律师考试 分
  • js 导出excel表格时身份证或数字过长会出现科学计数法

    问题描述 js在导出excel表格时身份证或数字过长会出现科学计数法 如E 13等 问题解决 td data t td 重点 style mso number format
  • json可视化在vue应用中的实现

    实现效果 json可视化化 代码 1 首先先下载好JsonView的组件 JsonView vue 组件代码如下
  • KVM-1、Linux 操作系统及虚拟化

    1 前言 一台计算机是由一堆硬件设备组合而成 在硬件之上是操作系统 操作系统与计算机硬件密不可分 操作系统用来管理所有的硬件资源提供服务 各个硬件设备是通过 总线 进行连接起来的 在操作系统之上 需要一个人机交互接口 我们才能使用计算机对其
  • 使用vue-cli脚手架工具搭建vue工程项目以及配置路由

    vue cli是用node编写的命令行工具 我们需要进行全局安装 打开命令行终端 输入如下命令 1 npm install g vue cli 这里使用的是npm 为了开发的便利 推荐安装cnpm 这样运行指令会更迅速 安装命令如下 1 n
  • 使用python对接海康威视的ISC(iSecureCenter)平台

    使用python如何对接ISC平台 获取视频 门禁 停车场等业务数据 步骤如下 1 登录海康的开放平台网站 open hikvision com 查看对接指南 2 正式开始编码 python导入jar包依赖库 需要导入ISC平台的安全认证库
  • C语言程序设计--综合训练20个任务

    程序设计综合训练 任务书 课程设计的意义 程序设计综合训练是电子信息工程 通信工程的专业实践课 属于专业必修课 作为一门程序设计语言 通过学习 掌握基本语法和一些常用函数 掌握程序设计的基本思想 熟悉常用的算法与编程技巧 掌握一般的排错能力
  • Excel VBA 提示“找不到工程或库”错误的解决办法

    前不久用Excel VBA给采购部做了个 供销存管理系统 结果在采购部的电脑上运行出现 找不到工程或库 的错误 一般情况下 出现此错误是因为找不到引用工程 或找不到与工程语言对应的引用的对象库 还有就是安装Office精简版也会出现此类错误
  • 卷积神经网络原理介绍

    1 人工神经网络 1 1 神经元 神经网络由大量的神经元相互连接而成 每个神经元接受线性组合的输入后 最开始只是简单的线性加权 后来给每个神经元加上了非线性的激活函数 从而进行非线性变换后输出 每两个神经元之间的连接代表加权值 称之为权重
  • 冒泡排序BubbleSort

    冒泡排序是一种时间复杂度为O n 的排序算法 一般情况下算是最慢的排序算法了 不过相对比较好理解属于入门级算法 实现思想很简单就是两个双层循环 挨个元素进行比较如果内层循环的位置比外层循环小 大 则进行位置交换 否则向后查找直到循环完毕 下
  • Ubuntu下gcc安装及使用

    Ubuntu下gcc安装及使用 2016年06月21日 10 58 37 29486人阅读 评论 2 收藏 举报 分类 Ubuntu 6 作者同类文章 X 目录 一安装 二编译 在Ubuntu下安装GCC和其他一些Linux系统有点不一样
  • 人工智能(AI)开发者线下实战训练营 - 立即免费报名

    免费报名请点击 https s growingio com kvVvdm
  • 调换windows键和Ctrl, 让window和macOS快捷键同意

    randyrants sharpkeys 亲测很好用 可以调换windows键和Ctrl https github com randyrants sharpkeys releases
  • 【千律】C++基础:类的静态成员变量和静态成员函数

    include
  • 数据库基础-入门看这篇

    数据库 引言 数据库时一个人机系统 由硬件 OS 数据库 DBMS 应用软件和数据库组成 一 数据库概述 1 1什么是数据 描述事物的符号记录包括数字 文字 图形 图像 声音 档案记录等 以 记录 形式按统一格式进行存储 数据是以 记录 的
  • 最小二乘拟合平面——直接求解法

    目录 一 算法原理 二 代码实现 1 python 2 matlab 三 算法效果 一 算法原理 平面方程的一般表达式为 A x B
  • 电脑怎么找到tomcat端口_查看tomcat端口号(怎么看tomcat的端口号)

    查看tomcat端口号 怎么看tomcat的端口号 2020 05 07 22 35 14 共10个回答 如何查看自己tomcat的端口号 首先我们需要知道 http的默认端口是80 也就copy是说 如果我们将端口号修改为80 输入网址的
  • “应用程序配置不正确,程序无法启动”详细举例

    参考资料 应用程序配置不正确 程序无法启动 的解决方法资料收集 内容我就不copy了 大家可以自己去看 总来说产生这个问题的原因可以归结如下 vc2005 vc2008采用了新的程序部署技术 manifest清单文件 manifest清单文