`
free_bird816
  • 浏览: 205926 次
  • 性别: Icon_minigender_1
  • 来自: 济南
社区版块
存档分类
最新评论

VS2008编译的程序在某些机器上运行提示“由于应用程序配置不正确,应用程序未能启动”的问题

阅读更多

VC9编译的程序在没有装过VC9(确切的说是.Net Framework3.5)的机器上运行时,如果提示“由于应用程序配置不正确,应用程序未能启动。重新安装应用程序可能会纠正这个问题。”这个错误,那么就说明该程序动态链接了VC9的运行时库,(如果还用到了MFC,那么可能动态链接了VC9的MFC库,同理还有ATL库),以及缺少对应的manifest文件,程序在目标机器上没有找到这些库和配置文件,因此导致了这个错误。出现这种情况的VC9编译器可能存在3个版本,接下来分别阐明:

1、没有打过任何补丁的VS2008

该版本对应的CRT/MFC/ATL库的版本号为9.0.21022.8,这个版本号在后面会用到。这个版本的程序部署比较简单,直接把VC安装目录下的redist目录(C:\Program Files\Microsoft Visual Studio 9.0\VC\redist)中需要的库以及对应的manifest文件拷贝到执行程序同目录下,这样程序到任何机器上都能够正常运行了。

2、打过SP1补丁的VS2008

打过该补丁后,系统中存在着两个版本的CRT/MFC/ATL库,版本号分别为9.0.21022.8和9.0.30729.1,这导致了manifest文件中记录的版本号和实际库的版本号不一致(程序要求它们的版本号一致才能运行)。这个版本的程序部署需要两个步骤,首先要使manifest文件中依赖项的版本号与实际库的版本号一致,均为9.0.30729.1,方法是在工程设置中增加一个宏定义_BIND_TO_CURRENT_VCLIBS_VERSION,该宏定义于C:\Program Files\Microsoft Visual Studio 9.0\VC\include\crtassem.h文件中,然后重新编译程序。接下来还是将VC安装目录下的redist目录(C:\Program Files\Microsoft Visual Studio 9.0\VC\redist)中需要的库以及对应的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 ATL 安全更新 (KB973675), 该补丁又将CRT/MFC/ATL库的版本号升级,为9.0.30729.4148,这次升级比较好,manifest文件与库的版本号一致了,不像SP1一样升级的不彻底。这样只需要在工程设置中增加一个宏定义_BIND_TO_CURRENT_VCLIBS_VERSION,接下来重新编译程序,然后直接把VC安装目录下的redist目录中需要的库以及对应的manifest文件拷贝到执行程序同目录下,这样程序到任何机器上都能够正常运行了。

顺便提一下,如果不想在发布程序时带上这些库和manifest文件(如果没有必要的话),那么可以采用静态编译CRT和MFC,然后把manifest文件添加到资源中,这样编译出的程序只要一个exe就可以在任何机器上直接运行了。

参考文章:

1、“应用程序配置不正确,程序无法启动”的解决方法资料收集:

有的时候,你在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升级到2008,2008的MFC库是9.0版本的,这个时候你的操作系统里面安装了两个版本的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文件)要运行起来的环境设置信息,文件名一般是可执行文件的文件全名加上.manifest。例如notepad.exe的manifest文件就应该是notepad.exe.manifest。例外有的程序将manifest文件直接嵌入到可执行文件的资源里面了,这也就是为什么有的时候你看不到程序的manifest文件的原因。通常来说,一个manifest文件的内容如下(test.exe.manifest文件):

 

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

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

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

    <security>

      <requestedPrivileges>

        <requestedExecutionLevel level='asInvoker' uiAccess='false' />

      </requestedPrivileges>

    </security>

</trustInfo>

<dependency>

    <dependentAssembly>

      <assemblyIdentity type='win32' name='Microsoft.VC90.DebugCRT' version='9.0.21022.8'

                        processorArchitecture='x86' publicKeyToken='1fc8b3b9a1e18e3b' />

    </dependentAssembly>

</dependency>

</assembly>

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

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

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

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

VS2008编译的程序在某些机器上运行提示由于应用程序配置不正确,应用程序未能启动的问题 - tangxingqt - doomgnu的博客

解决方案

知道了程序依赖于具体哪一个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包安装上就可以了。

 

附:解决方案参考:

方案一:


方法一:
在C:\Program Files\Microsoft Visual Studio 8\VC\redi
st\Debug_NonRedist\x86\Microsoft.VC80.DebugCRT 下找到了下列文件:

msvcm80d.dll
msvcp80d.dll
msvcr80d.dll
Microsoft.VC80.DebugCRT.manifest

把这几个文件拷贝到目标机器上,与运行程序同一文件夹或放到system32下,就可以运行那个程序了。

其他release版,MFC程序什么的都是拷redist下相应文件夹下的文件就可以了,文件夹后都有标识!

方法二:
修改编译选项,将/MD或/MDd 改为 /MT或/MTd,这样就实现了对VC运行时库的静态链接,在运行时就不再需要VC的dll了。

方法三:

工程-》属性-》配置属性-》常规-》MFC的使用,选择"在静态库中使用mfc"
这样生成的exe文件应该就可以在其他机器上跑了。

方法四:

你的vc8安装盘上找到再分发包vcredist_xxx.exe和你的程序捆绑安装

 

我逐一测试下来,直到第三个方法才成功.第二个方法不知道在哪里修改编译选项所以放弃了,第四个方法不喜欢,这跟直接安装.net framework 2.0 有什么区别吗?还不如直接安装.net framework 2.0 呢.

 

     方案二:

最早出现这个错误我和许多人认为的一样
认为是缺乏DLL库文件导致.但是在测试机复制了DLL甚至安装了.net framework 2.0以后
都无法解决问题,最后确认不是由缺乏DLL所致
因为程序是纯win32的应用程,非托管代码,所以也无需.net framework

Visual C++2003/2005默认的MFC程序是使用动态MFC库(Use MFC in a Shared DLL)来链接的
而动态MFC库使用的是Multi-threaded DLL (/MD)
由于XP对于PE文件格式监测更加严格.
就会导致部分使用多线程DLL的可执行文件在调用的时候出错
修改项目属性的编译开关
Project->Property->configuration Properties->C/C++->Code Generation->Runtime Library
修改成Multi-threaded (/MT)
修改了Runtime类型以后
需要将MFC的编译类型也改成静态库
Project->Property->configuration Properties->General->Use of MFC
修改成Use MFC in a Static Library

一部分情况下在这步就能解决问题
另外一部分情况会遇见如下情况
编译器报错



CODE:
nafxcw.lib(afxmem.obj) : error LNK2005: "void * __cdecl operator new[](unsigned int)" (??_U@YAPAXI@Z) already defined in libcpmt.lib(newaop.obj)
[Copy to clipboard]


产生这个问题的原因是库依赖关系
在Project->Property->configuration Properties->Linker->Command Line
加入编译开关/verbose:lib可以显示详细的库链接顺序
CODE:

------ Build started: Project: PerfMonDemo, Configuration: Release Win32 ------
Linking...
Searching libraries
Searching d:\Program Files\Microsoft Visual Studio 8\VC\PlatformSDK\lib\pdh.lib:
Searching d:\Program Files\Microsoft Visual Studio 8\VC\lib\DelayImp.lib:
.................
Searching d:\Program Files\Microsoft Visual Studio 8\VC\atlmfc\lib\nafxcw.lib:
Finished searching libraries
.\Release/PerfMonDemo.exe : fatal error LNK1169: one or more multiply defined symbols found
Build log was saved at "file://d:\Dev\Performance Monitor\Release\BuildLog.htm"
PerfMonDemo - 2 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

[Copy to clipboard]

我们发现在libcpmt.lib声明过的operator new在nafxcw.lib中再次定义
解决方法如下
Project->Property->configuration Properties->Linker->Input->Additional Dependencies
加入
nafxcw.lib
libcpmt.lib
Project->Property->configuration Properties->Linker->Input->Ignore Specific Library
加入
nafxcw.lib
libcpmt.lib
这样链接程序就不会先按照默认顺序来连接这两个库文件
而是在最后在加入对他们的引用.这样就避免了这个问题
下面是一张可能发生冲突的列表
若要使用此运行时库 请忽略这些库
单线程 (libc.lib) libcmt.lib、msvcrt.lib、libcd.lib、libcmtd.lib、msvcrtd.lib
多线程 (libcmt.lib) libc.lib、msvcrt.lib、libcd.lib、libcmtd.lib、msvcrtd.lib
使用 DLL 的多线程 (msvcrt.lib) libc.lib、libcmt.lib、libcd.lib、libcmtd.lib、msvcrtd.lib
调试单线程 (libcd.lib) libc.lib、libcmt.lib、msvcrt.lib、libcmtd.lib、msvcrtd.lib
调试多线程 (libcmtd.lib) libc.lib、libcmt.lib、msvcrt.lib、libcd.lib、msvcrtd.lib
使用 DLL 的调试多线程 (msvcrtd.lib) libc.lib、libcmt.lib、msvcrt.lib、libcd.lib、libcmtd.lib

分享到:
评论

相关推荐

    [VS2005]解决“由于应用程序的配置不正确,应用程序未能启动,重新安装应用程序可能会纠正这个问题”

    今天在准备发布用VS2005写的那个程序时,拷贝到我同事机器上,双击突然出现了“由于应用程序的配置不正确,应用程序未能启动,重新安装应用程序可能会纠正这个问题“,这个问题很让我意外,以前只出现过缺少DLL的...

    解决“由于应用程序配置不正确,应用程序未能启动...”的问题

    标题中的问题“由于应用程序配置不正确,应用程序未能启动…”通常是由于C++运行时库缺失或者版本不匹配导致的。在Windows系统中,许多应用程序依赖于Microsoft Visual C++ Redistributable包来运行,这些包提供了...

    vs2008 运行环境解决“由于应用程序配置不正确

    标题中的“vs2008 运行环境解决‘由于应用程序配置不正确’”提示了我们在使用Visual Studio 2008(VS2008)开发的C++应用程序时,可能会遇到的一个常见问题,即应用程序在运行时由于缺少必要的运行时库或配置错误而...

    vs2008 编译的程序运行有配置问题解决

    标题“vs2008 编译的程序运行有配置问题解决”直指这类问题,而描述则提供了解决方案的线索。这里我们将深入探讨如何处理这些配置错误,以及提到的几个关键文件的作用。 首先,我们来看一下VS2008编译的程序可能...

    Linux下打包发布QT程序,并运行在其他没有安装QT环境或多个QT环境的linux系统上

    2. **静态编译Qt库**:为了使程序能在没有Qt环境的系统上运行,我们需将Qt库与应用程序一起静态链接。这意味着在编译Qt应用程序时,所有的Qt库文件会被合并到可执行文件中。这可以通过修改Qt的配置选项(如使用`...

    应用程序无法正常启动0xc0150002 解决方案

    标题中的“应用程序无法正常启动0xc0150002”是一个常见的错误代码,它通常出现在尝试运行依赖于特定动态链接库(DLL)文件的应用程序时。这个错误表明系统在寻找并加载必要的运行时库时遇到了问题。0xc0150002错误...

    VC++运行库解决2008等系统出现QQ等程序出现配置不正确问题

    标题中的“VC++运行库解决2008等系统出现QQ等程序出现配置不正确问题”指的是在Windows 2008系统上,部分应用程序(如QQ)由于缺少必要的Microsoft Visual C++运行库组件,可能会报错“配置不正确”。这通常是因为...

    windows服务启动另外一个应用程序

    在Windows操作系统中,服务(Service)是一种后台运行的程序,它们通常不与用户交互,而是为系统或应用程序提供特定的功能。Windows服务的一大特点是它们可以在用户登录之前启动,且不受当前登录会话的影响,这使得...

    GraalVM将Java应用程序编译为本机可执行程序,这些可执行程序可以立即快速启动并使用更少的计算资源.zip

    GraalVM Native Image是一种静态编译技术,它将Java应用程序及其依赖库预先编译成机器码,形成一个无需JVM即可运行的独立可执行文件。通过这种方式,应用程序在启动时不需要经历传统的类加载、解析和初始化过程,...

    vs2008 CRT运行库,MFC运行库(Debug、Release)

    然而,对于那些没有安装VS2008或其运行库的用户来说,尝试运行由VS2008编译的程序可能会遇到“应用程序配置不正确”的错误。为了确保程序在不同环境中能够正常运行,我们需要提供必要的运行库支持。 **1. CRT运行库...

    VC++运行库全版(2005、2008、2010)(x86和x64)

    然而,这些运行时库并不是系统自带的,因此有时用户在尝试运行某些应用时,可能会遇到"由于应用程序的配置不正确,应用程序未能启动,重新安装应用程序可能会纠正这个问题"的错误提示,这通常是因为缺少相应的VC++...

    vs编译win7下默认管理员执行程序方法

    总之,在Windows 7环境中使用VS2008或VS2010编译程序时,通过正确配置项目属性和应用程序清单文件,可以轻松实现应用程序以管理员权限运行的目标。这不仅可以帮助开发者解决某些特定的问题,还能提高应用程序的安全...

    编译原理答案(编译原理及编译程序构造)

    编译程序是指把由高级程序语言编写的源程序转换为一台具体计算机的机器语言或汇编语言程序的翻译程序。遍是指对源程序或源程序的中间形式从头到尾扫描一遍,并做有关的加工处理,生成新的源程序的中间形式或目标程序...

    Windows上ZLMediakit编译后可直接运行版本(带外置配置文件和运行可能所需dll依赖)

    在Windows操作系统上,为了便于用户使用,提供了预编译的可以直接运行的版本,包括必要的配置文件和运行时依赖的动态链接库(dll)文件。 在Windows上部署ZLMediaKit,首先需要了解ZLMediaKit的基本架构和功能。...

    无法定位程序输入点于动态链接库上的问题1

    然而,在这个问题中,`windeployqt`由于路径设置的原因未能正确工作。 4. **环境变量问题**:在上述情况下,需要调整环境变量中的Qt路径,确保mingW版本的Qt路径优先于msvc2015版本。这样,`windeployqt`会从正确的...

    应用程序无法正常启动0xc000007b修复dll

    标题中的“应用程序无法正常启动0xc000007b”是一个常见的错误代码,它在Windows操作系统中出现,特别是当用户尝试运行某些应用程序时。这个错误通常与动态链接库(DLL)文件有关,这些文件是Windows系统和应用程序...

    MFC程序运行所需库

    在开发MFC程序时,开发者需要确保他们的程序链接了正确的MFC库,并且在目标机器上安装了相应的运行时环境。对于发布MFC程序,通常需要包含这些运行时库的 redistributable 包,以便用户在没有安装完整Visual Studio...

    解决WIN7SP1下编译的VS6.0程序(ADO2.8)在其它客户端下需无法使用的问题

    在Windows 7 SP1环境下,使用Visual Studio 6.0(VS6.0)开发的程序,特别是那些依赖于ADO 2.8的项目,可能会遇到在其他客户端计算机上运行时的问题。这个问题主要体现在程序无法正常运行或者出现错误,这通常是由于...

    vs2008运行库

    描述中提到,“vs2008开发的程序,放在别的电脑上不能运行”,这是因为目标计算机可能缺乏必要的运行时库。Visual Studio 2008运行库包含了运行基于.NET Framework 3.5和VC++ 2008的程序所需的各种DLL文件,如msvcr...

    VS2013+OpenCV 2.4.9项目生成EXE文件如何在其他电脑上直接运行

    ### VS2013+OpenCV 2.4.9项目生成EXE文件并在其他电脑上直接运行 本文主要介绍如何使用Visual Studio 2013结合OpenCV 2.4.9创建一个C++(及MFC)项目,并将其打包成可以在其他未安装VS或OpenCV的计算机上直接运行的...

Global site tag (gtag.js) - Google Analytics