最近做了一个MSI程序安装包的修改,涉及的东西蛮多的,记录下来以作参考。鉴于程序的私密性,在这里就不多介绍了,只说技术。
扯点别的先。
一、MSI与EXE的区别
【EXE】文件是最常见的可执行应用程序文件,是一种可在操作系统存储空间中浮动定位的可执行程序,在MSDOS和MSWINDOWS下可执行文件的扩展名为EXE。在Windows下二进制的可执行程序有COM,EXE,DLL等,COM一般用作DOS可执行文件的扩展名,EXE一般用作Windows下可执行文件的扩展名,而DLL为动态链接库文件。通常用户在提示行中输入不带 .exe 扩展名的文件名后按 Enter 键就能运行可执行程序。
EXE文件比较复杂,每个EXE文件都有一个文件头,结构如下:
EXE 文件头信息
EXEHEADER ENDS 程序映象,包含处理器代码和程序的初始数据,紧接在文件头之后。它的大小以字节为单位,等于.EXE文件的大小减去文件头的大小,也等于exHeaderSize的域的值乘以16。MS-DOS通过把该映象直接从文件拷贝到内存加载.EXE程序然后调整定位表中说明的可重定位段地址。而定位表是一个重定位指针数组,每个指向程序映象中的可重定位段地址。文件头中的exRelocItems域说明了数组中指针的个数,exRelocTable域说明了分配表的起始文件偏移量。每个重定位指针由两个16位值组成:偏移量和段值。为加载.EXE程序,MS-DOS首先读文件头以确定.EXE标志并计算程序映象的大小,然后它试图申请内存。
首先,它计算程序映象文件的大小加上PSP的大小再加上EXEHEADER结构中的exMinAlloc域说明的内存大小这三者之和,如果总和超过最大可用内存块的大小,则MS-DOS停止加载程序并返回一个出错值。否则面,它计算程序映象的大小加上PSP的大小再加上EXEHEADER结构中exMaxAlloc域说明的内存大小之和,如果第二个总和小于最大可用内存块的大小,则MS-DOS 分配计算得到的内存量。否则,它分配最大可用内存块。分配完内存后,MS-DOS确定段地址,也称为起始段地址,MS-DOS从此处加载程序映象,如果exMinAlloc域和exMaxAlloc域中的值都为零,则MS-DOS把映象尽可能地加载到内存最高端。否则,它把映象加载到紧挨着PSP域之上。接下来,MS-DOS读取重定位表中的项目调整所有由可重定位指针说明的段地址。对于重定位表中的每个指针,MS-DOS寻找程序映象中相应的可重定位段地址,并把起始段地址加到它之上。一旦调整完毕,段地址便指向了内存中被加载程序的代码和数据段。 MS-DOS在所分配内存的最低部分建造256字节的PSP,把AL和AH设置为加载 .COM程序时所设置的值。MS-DOS使用文件头中的值设置SP与SS,调整SS初始值,把起始地址加到它之上。MS-DOS还把ES和DS设置为PSP的段地址.最后,MS-DOS从程序文件头读取CS和IP的初始值,把起始段地址加到CS之上,把控制转移到位于调整后地址处的程序。
DLL(Dynamic Linkable Library)文件即动态链接库文件,是一种可执行文件,它允许程序共享执行特殊任务所必需的代码和其他资源。一般来说,DLL是一种磁盘文件,以 .dll,.DRV,.FON,.SYS 和许多以 .EXE 为扩展名的系统文件都可以是 DLL。它由全局数据、服务函数和资源组成,在运行时被系统加载到调用进程的虚拟空间中,成为调用进程的一部分。如果与其它 DLL 之间没有冲突,该文件通常映射到进程虚拟空间的同一地址上。DLL 模块中包含各种导出函数,用于向外界提供服务。DLL 可以有自己的数据段,但没有自己的堆栈,使用与调用它的应用程序相同的堆栈模式;一个 DLL 在内存中只有一个实例;DLL 实现了代码封装性;DLL 的编制与具体的编程语言及编译器无关。
【MSI】文件,不得不先说说Windows Installer,它不只是安装程序,而是可扩展的软件管理系统。Windows Installer的用途包括:管理软件的安装、管理软件组件的添加和删除、监视文件的复原以及使用回滚技术维护基本的灾难恢复。另外,Windows Installer还支持从多个源位置安装和运行软件,而且可以由想要安装自定义程序的开发人员自定义。要想使用这些功能,就必须通过MSI文件。MSI 文件是Windows Installer的数据包,它实际上是一个数据库,包含安装一种产品所需要的信息和在很多安装情形下安装(和卸载)程序所需的指令和数据。MSI文件将程序的组成文件与功能关联起来。此外,它还包含有关安装过程本身的信息:如安装序列、目标文件夹路径、系统依赖项、安装选项和控制安装过程的属性。
Windows Installer技术就是合并在一起发挥作用的两个部分:客户端安装程序服务(Msiexec.exe)和Microsoft软件安装(MSI)软件包文件。 Msiexec.exe 程序是 Windows Installer 的一个组件。当 Msiexec.exe 被安装程序调用时,它将用 Msi.dll 读取软件包文件 (.msi)、应用转换文件 (.mst) 并合并由安装程序提供的命令行选项。 Windows Installer 执行所有与安装有关的任务:包括将文件复制到硬盘、修改注册表、创建桌面快捷方式、必要时显示提示对话框以便用户输入安装首选项。
当双击MSI文件的时候,与之关联的Windows Installer 的一个文件Msiexec.exe 被调用,它将用Msi.dll读取软件包文件(.msi)、应用转换文件(.mst)进行进一步处理,然后 Windows Installer 执行所有与安装有关的任务:包括将文件复制到硬盘、修改注册表、创建桌面快捷方式,必要时显示提示对话框以便用户输入安装需要的信息,就这样,一个程序安装到了你的电脑上。采用MSI安装的优势在于你可以随时彻底删除它们,更改安装选项,即使安装中途出现意想不到的错误,一样可以安全地恢复到以前的状态,正是凭着此强大功能,越来越多的软件开始使用MSI作为发行的方式了。如果你对MSI文件感兴趣,可以用WinRAR等压缩软件打开看一下里面的内容。
二、制作MSI常用的工具
【Installshield】
最常用的工具就是Installshield。Macrovision 软件公司家族成员之一的InstallShield产品,是安装工具领域事实上的标准。InstallShield 软件是软件安装、配置软件包和升级解决方案领域内公认的标准。 InstallShield已经成为安全安装软件的标准解决方案,涉及全球6.9万多个开发组织和5亿台电脑。主流的MSI应用程序均采用该模式打包发布。该软件功能强大,简单的安装操作容易,复杂的安装过程及组件配置需要自己动手写脚本,教程可以在网上搜索,能搜出一大堆出来,推荐“海洋女神”的博客,写的很好很详细。
【Advanced Installer】
Advanced Installer 是一款 Windows Installer 编写工具。它为创建和维护基于 Windows Installer 安装技术的安装程序包 (EXE、MSI 等) 提供了一个简单易用的图形用户界面。Advanced Installer 有 4 个版本: 免费版、专业版、Java 和企业版。免费版不需要注册,并且可以免费用于商业和非商业性目的。专业版、Java 版和企业版有一个只能被用于评估目的试用期。在试用期结束以后,您必须注册产品或完全停止使用它。Advanced Installer 是一款功能强大、可生成符合 MS Windows 认证的 Windows Installer 的 MSI 安装包制作工具,具有友好的图形用户界面,直观而且非常简单的界面,创建 MSI 文件包非常方便,用户只需添加文件,修改名称,添加按钮就可以了,无需任何脚本方面的知识,并且生成的安装文件保证符合 Windows 最佳操作建议。
Advanced Installer具有完全安装、注册和卸载组成你应用程序的文件、部件及资源的功能;完全自定义 MSI 安装包 -具有添加、删除文件及文件夹功能; 添加或移除内、外部文件或 URL 快捷方式;添加或移除注册表键或项目;添加或移除环境变量;安装时可设置文件属性 - 只读、隐藏等;强制安装完毕系统重启动;支持使用 64 位 CPU 的系统中安装包制作;Windows 系统下安装过程完整日志等特点。
【MSI_Studio】
MSI Studio是一个用来创建Windows Installer(MSI)文件,也可以修改现有Windows安装包(MSI格式安装文件)的工具,Desktop Authority MSI Studio是为全球系统管理人员,软件打包人员和开发人员提供的完善的软件解决方案 。MSIStudio的主要功能有:重新打包– 从原有的或者现有的基于MSI的安装创建定制的MSI;编辑 – 通过图像浏览或直接访问MSI表格修改MSI;管理– 通过先进的转化,合并,确认和提取功能改善你的MSI;建造– 使用cab文件,压缩的MSI,引导的MSI和证书创建MSI项目;精简版说明:去除服务器组件,去除旧的VB/VC运行库,重新压缩cab以获得更小的体积,部分修改安装对话框 ,修改默认安装目录为%Programfiles%\ScriptLogic Corporation\MSI Studio(以前后面还要再多一个\MSI Studio)。
【Orca】
Orca 是一款由微软提供的用于 Windows Installer 数据库表编辑器。可用来编辑 Windows Installer 数据库文件 (.msi) 文件,合并模块 (.msm) 文件,补丁 (.msp) 文件,内部一致性计算程序 (.cub) 文件和补丁创建属性 (.pcp) 文件。是修改和本地化 Windows Installer 数据库的最佳辅助工具。 Orca主要特点有:可以任意添加、删除、导入、导出和重新构架数据表;可以任意复制、粘贴、添加、删除、编辑行和单元格;可以用十进制或十六进制查看数据型单元格;可以创建、应用转换 (.mst) 文件;可以对数据库进行验证,合并模块以及对话框御览;可以查看并修改摘要信息;
类似的这些软件网上应该还有很多,限于能力有限,只找到常用的这几个。介绍均来自百度百科。
三、本次修改的经过
软件简介:本次修改的软件是一个VC++开发的MIS程序,为了简便,领导想把一个空的数据库文件打包进入,技术支持部通常再给客户安装完软件后都会重新把安装目录修改,添加一些其他文件,这样一来,软件就显得很弱智,他们提出的要求也很明确,添加数据库包,修改安装后路径,更改桌面图标名称为中文。很不幸的是,我没有源代码,手头上只有一个安装包(.MSI),更要命的是用Winrar打开时显示该数据包已损坏,其实程序仍可以安装的,而且程序挪动地方一样可以运行的。我还一度怀疑这是一个“绿色的”软件呢,如果是那样的话就重新用IS封装一个安装包,加入其他部门所需的文件即可,但是这样做下来没有成功,用IS编辑软件包也没有发现其他奇特之处,只是系统一直提示“由于应用程序的配置不正确,应用程序未能启动,重新安装应用程序可能会纠正这个问题”,重新安装是不能解决这种问题的。而这个问题也是很多人一直在问的问题,以前用VC6和VS2003的话, 如果缺少库文件,是会提示缺少“**.dll”,但是用VS2005却没有这样的提示。用记事本直接打开MSI文件,在文件结尾处可以看到一下内容:
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="Microsoft.VC80.DebugCRT" version="8.0.50608.0" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity>
</dependentAssembly>
</dependency>
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="Microsoft.VC80.DebugMFC" version="8.0.50608.0" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity>
</dependentAssembly>
</dependency>
</assembly>
很明显,软件缺相关的DLL文件。根据网上众多专家的博客,我做了尝试。由于不可能重新编译,我先尝试了拷贝文件的方法:在类似C:\Program Files\Microsoft Visual Studio 8\VC\redist\Debug_NonRedist\x86\Microsoft.VC80.DebugCRT 下找到了下列文件: msvcm80d.dll、msvcp80d.dll、msvcr80d.dll、Microsoft.VC80.DebugCRT.manifest ;把这几个文件拷贝到目标机器上,与运行程序同一文件夹或放到system32下,不能运行;然后我又找到了再分发包vcredist_xxx.exe,想把程序一起捆绑安装,一样不行。也许还缺文件,但是此时IS已经不能发挥作用了,而且IS职能修改部分属性值,但不能加入新文件,更不能重新Building,这个给我造成了不小的麻烦。现在要做的是先查明缺失的系统文件,再做一个移植,重新打包新文件。一番搜索后,我找到了Orca。说实话,打开Orca的界面的时候,我一点心思都没有了,几乎全部是表,操作异常麻烦,稍有不慎,就BreakDown了。但是项目在那里摆着的,而且在我不知情的时候向老板吹牛皮夸下海口,现在骑虎难下了,硬着头皮,继续寻找吧。这次搜到的就是Advanced Installer。Advanced Installer的界面就清爽很多,和IS很类似,我按照之前的设想,先修改了软件的属性,然后添加目录,编译,程序BreakDown(我用的破解版的)。我再次打开重复一遍,仍旧崩溃,我也要崩溃了。我又重新用了其自动搜索识别功能,这次居然把我之前要查找的隐藏的系统文件导出来了,悲喜交加呀。我把这些导出的文件和先前安装后的程序自身文件捆绑后打包,依旧不能运行。崩溃!
查资料到现在,三四天了,每次都像玻璃瓶里的苍蝇,以为看到光明了,一头撞上去,血肉模糊啊!我打算放弃了,为了这样一个功能,不值得。我删除了之前导出的那些文件,草纸上的几个Action被我一个个划去,正准备扔掉的时候,我仍旧不死心,再次检查了一遍,看看是不是哪里漏掉了,然后再次搜索工具,最后,找到了一个利器--MSI Studio。我告诉自己,这次不行,坚决放弃。
MSI Studio虽然是全英文界面,但是难不住我。MSI Studio和IS也很像,操作起来也很类似,最好的就是这个支持重新编译,我很小心的操作着这个最后的稻草,第一次显示错误,我先添加一个Readme文件,编译,成功,安装测试,成功,窃喜。然后加入新文件夹,添加新文件,在Features和Components中添加文件夹,注入文件,编译,Done,额滴神呐!
四天的努力,换来了现在这个结果。然后打开虚拟机,在一个纯净的操作系统下测试,通过,哦也!