VC 软件发布的故事(1)
2015-01-17 21:48
190 查看
当我们兴冲冲把自己写的小程序传给朋友,亦或是正式发布产品到用户手中,时常会遇到“由于应用程序的配置不正确,应用程序未能启动,重新安装应用程序可能会纠正这个问题”。
这么个提示实在是让人有点气馁啊,那么怎么解决呢,是什么导致这个问题呢?
(注意,本文不涉及msvc7.x,因为这个版本的两个主要产品我接触很少)
首先,静态链接所有库是不会遇到这个问题的,但不是所有情况下我们都能静态链接所有库,特别是存在MFC扩展dll的时候,以及使用了没有static lib的第三方库的时候(这些库可能要求动态链接msvcrt)。
msvc6时代没这个问题,因为程序不能运行会提示缺少xxx.dll,这样很容易解决,只需要把必要的dll和软件一起发布就可以了(这个需要注意dll作者的再发布许可协议)。
msvc8,msvc9引入了所谓的程序集概念(注意不是.net那个意义的程序集,但是借助于这个概念)使用winsxs来避免dll hell,但是(嗯,大家都怕这个但是)却引入了另一个问题:版本匹配。
假设下列场景:
1 我们编译环境是msvc8或者msvc9,并且始终安装最新的补丁
2 发布给用户编译出来的binary和msvc8/msvc8sp1/msvc9/msvc9sp1 redist
3 运行失败
这实在是令人倍感挫折,为什么不行了呢?问题的根源在menifest,如果我们打开binary随带的menifest,并且检查相关dll的版本号,会发现版本号远高于msvc redist里面的,这将导致系统拒绝加载dll,表面现象就是
“由于应用程序的配置不正确,应用程序未能启动,重新安装应用程序可能会纠正这个问题”。
结论:编译环境的补丁会将编译环境的头文件升级,导致默认配置编译出来的binary需求更高级的版本号。
解决办法:
msvc8:定义 _USE_RTM_VERSION 宏,这将强制编译出使用msvc8 rtm版本号的bingary。
msvc9:取消定义 _BIND_TO_CURRENT_VCLIBS_VERSION 宏,这将编译出使用msvc9 rtm版本号的bingary。
这样,使用标准的msvc8/msvc8sp1/msvc9/msvc9sp1 redist即可。
msvc10微软取消了之前的设计,回归了msvc6的做法,于是正确的发布应该是下面这样
静态链接:这个兼容问题最少,但是无法享受系统补丁带来的安全和改进。
动态链接:可以依赖系统目录下的msvcrt dll,这样系统打补丁就会自动享受系统更新带来的改进。也可以把msvcrt和自己的binary放在一起,这样便享受不到系统更新。
补充说明:有极少数用户报告即便拷贝msvcrt100.dll之类的文件到系统目录或者binary目录,也无法运行,我无法重现,不知道具体原因。
这么个提示实在是让人有点气馁啊,那么怎么解决呢,是什么导致这个问题呢?
(注意,本文不涉及msvc7.x,因为这个版本的两个主要产品我接触很少)
首先,静态链接所有库是不会遇到这个问题的,但不是所有情况下我们都能静态链接所有库,特别是存在MFC扩展dll的时候,以及使用了没有static lib的第三方库的时候(这些库可能要求动态链接msvcrt)。
msvc6时代没这个问题,因为程序不能运行会提示缺少xxx.dll,这样很容易解决,只需要把必要的dll和软件一起发布就可以了(这个需要注意dll作者的再发布许可协议)。
msvc8,msvc9引入了所谓的程序集概念(注意不是.net那个意义的程序集,但是借助于这个概念)使用winsxs来避免dll hell,但是(嗯,大家都怕这个但是)却引入了另一个问题:版本匹配。
假设下列场景:
1 我们编译环境是msvc8或者msvc9,并且始终安装最新的补丁
2 发布给用户编译出来的binary和msvc8/msvc8sp1/msvc9/msvc9sp1 redist
3 运行失败
这实在是令人倍感挫折,为什么不行了呢?问题的根源在menifest,如果我们打开binary随带的menifest,并且检查相关dll的版本号,会发现版本号远高于msvc redist里面的,这将导致系统拒绝加载dll,表面现象就是
“由于应用程序的配置不正确,应用程序未能启动,重新安装应用程序可能会纠正这个问题”。
结论:编译环境的补丁会将编译环境的头文件升级,导致默认配置编译出来的binary需求更高级的版本号。
解决办法:
msvc8:定义 _USE_RTM_VERSION 宏,这将强制编译出使用msvc8 rtm版本号的bingary。
msvc9:取消定义 _BIND_TO_CURRENT_VCLIBS_VERSION 宏,这将编译出使用msvc9 rtm版本号的bingary。
这样,使用标准的msvc8/msvc8sp1/msvc9/msvc9sp1 redist即可。
msvc10微软取消了之前的设计,回归了msvc6的做法,于是正确的发布应该是下面这样
静态链接:这个兼容问题最少,但是无法享受系统补丁带来的安全和改进。
动态链接:可以依赖系统目录下的msvcrt dll,这样系统打补丁就会自动享受系统更新带来的改进。也可以把msvcrt和自己的binary放在一起,这样便享受不到系统更新。
补充说明:有极少数用户报告即便拷贝msvcrt100.dll之类的文件到系统目录或者binary目录,也无法运行,我无法重现,不知道具体原因。
相关文章推荐
- VC2008发布程序时指定库版本 || 详解“由于应用程序配置不正确,应用程序未能启动” || vc2008 发布你的软件
- VC2005/VS2005 VC2008/VS2008 发布软件 部署问题解决
- VS2008(VC9)基于OpencasCade发布软件 以及 sxstrace.exe 工具的使用
- 用VC++实现软件的多语种支持 作者:卞远
- [导入]用VC制作带有滚动字幕的软件封面
- Blog发布软件的构想
- [代码发布]ASP/COM+组件开发辅助软件
- 用VC制作带有滚动字幕的软件封面
- [转载]一个软件,从零到发布(.tar.gz)
- 微软收购一软件公司 即将发布反间谍件工具
- 微软即将发布杀毒软件 可通过自动更新下载
- NHibernate0.7 发布,软件基础开发平台以及在软件基础开发平台中使用O/R Mapping
- 免费发布“两千年中西历速查”软件,对历史或历法没兴趣的就不要下载了
- VC#2005 最新技术预览版下周发布
- Maxtor发布整合Dantz软件的OneTouch II外置硬盘
- 用VC++实现软件的多语种支持
- 用VC++搞定应用软件图标
- 免费发布“两千年中西历速查”软件,对历史或历法没兴趣的就不要下载了
- 用VC++实现软件的多语种支持
- 软件测试工程师试题发布版