zoukankan      html  css  js  c++  java
  • Msi中文件替换

    转自https://blog.csdn.net/davidhsing/article/details/9962377

    ※说明:
    目前可以用于MSI编辑的软件很多,但是有些软件在保存时会在MSI文件中写入一些自己的表或内容,有些会另外嵌入一个CAB文件,使得MSI文件增大。而这里提供的方法保证不会写入任何不必要的内容和文件。

    ※关键点:
    1、CAB中的文件顺序要和MSI的文件表中的文件顺序保持一致。
    2、有些CAB中的文件使用了Windows不支持的文件名。
     

    软件准备


    1、Orca,微软提供的MSI编辑器。汉化版下载地址(版本为 4.5.6001.22192):
    http://www.hanzify.org/index.php?Go=Show::List&ID=11122 或
    http://www.wanfutrade.com/software/hanhua/Orca45chs.msi

    2、MsiDb,微软提供的MSI中CAB文件提取和替换工具。本人的汉化版下载地址(版本为4.5.6001.22192):
    http://www.wanfutrade.com/software/hanhua/MsiDb.exe(链接不可用了)

    3、IExpress,微软提供的CAB文件打包用户界面工具。本人的汉化版下载地址(版本为6.0.3790.0):
    http://www.wanfutrade.com/software/hanhua/iexpress20.exe(链接不可用了)

    4、Excel,相信这个大家都有吧。什么版本都可以。

    基础知识


    1、MSI文件的格式
    MSI文件实际上一个安装数据库,里面有很多表,这些表都是由 TAB 格式写成的文本,就像EXCEL一样由列和行组成。可以从MSI中导出每个表。导出的表可以用文本编辑器和EXCEL打开。至于每个表和表中每个字段的作用就不在这里讲述了。请参考微软提供的相关资料。

    2、MSI安装文件存在形式
    MSI 安装程序中,需要安装的文件的存在形式许多种,常见的有以下几种:
    (1)安装文件被打包为CAB文件,并嵌入在MSI文件中
    (2)安装文件被打包为CAB文件,但CAB独立于MSI存在
    (3)安装文件未被打包为CAB文件,而是以原来的状态存在于各个文件夹中
    对于以(1)、(2)形式存在的CAB文件,可以采用本文介绍的方法替换,而对于以(3)形式存在的文件文件直接替换即可。

    3、MSI安装文件列表
    在MSI文件中有二个表是用来表达CAB中的文件列表和CAB文件的名称和文件数以及其他信息的,这就是 File 表和 Media 表,其中File表保存了CAB中存在的文件名以及每个文件所属的组件、安装后的实际文件名、文件大小、版本、语言、属性和文件顺序等信息,Media表保存了CAB文件的磁盘ID、文件数、磁盘描述、CAB文件名以及卷标等信息。
    先来看一下MSI文件中这二个表:
    (1)File表
     


    上面就是File表,对涉及到本主题的列说明如下:
    File列,表示 CAB中的文件名列表,有的是我们常见的文件名格式,有的则在常见文件名后加上许多像类 ID那样的编号,有的干脆就是一个编号。对为什么不用常见的文件名,我想是由于有的MSI制作软件为了某种目的故意这样命名的。特别是InstallShield制作的MSI文件。
    Compoent_ 列,表示该文件属于哪个组件。
    FileName 列,表示安装后的文件名。其中 | 前面的为短文件名,后面的为长文件名。
    FileSize 列,表示文件的大小。一般不需要更改它,即使替换后的文件与其不一致。
    Language 列,表示文件所用的语言。一般也不需要更改它,即使替换后的文件语言与其不一致。
    Attributes 列,表示文件的属性,比如隐藏、系统、存档等等。一般也不需要更改它,除非您有特别的用途,如想在安装后隐藏某个文件。
    Sequenec 列,表示文件的序号,这里的需要不允许重复,并且始终是从1开始的。

    (2)Media表


    Media表中,DiskID、DiskPrompt、VolumeLable、Source列一般不需要去考虑,这里主要介绍以下其他二个列。
    LastSequence 列,表示CAB中的文件数,也就是上述File表中Sequenec 列中的最大数,这二个数一定要一致。
    Cabinet 列,表示 CAB文件名。注意:文件名前的"#"不是真正文件名的一部分。

    开始实践


    1、首先提取嵌入在MSI中的CAB文件。如果是CAB文件独立于MSI,跳过该操作。
      在DOS下或MsiDb.exe快捷方式下,使用"MsiDb.exe –x CAB文件名 -d MSI文件名"命令提取。
    其中:(1)CAB文件名就是Media表中的Cabinet 列中的CAB文件名。注意忽略前置的"#"。
    (2)CAB 和 MSI 文件名均要带后缀扩展名。

    2、直接用Windows 资源管理器或RAR或其他压缩软件提取CAB文件中的文件到一个单独的文件夹。

    3、使用CMD命令,转入DOS界面,在释放CAB中的文件的单独文件夹下,使用"dir /b > CabFileList.xls"命令提取该文件夹中的文件名列表。这里的CabFileList.xls文件名您可以用其他文件名代替,自由命名。

    4、用MsiDb.exe或Orca打开MSI文件,导出MSI文件中的File表。导出后的文件名为File.idt。

    5、用EXCEL打开File.idt文件,并按 Sequenec 列对整个表进行排序备用。如下图。



    6、比较从CAB中提取的文件数量是否与MSI文件中的File表中所列的文件数量相等。可以直接在MSI文件和解开的文件夹中判断,也可以用EXCEL分别打开前面生成的CabFileList.xls和File.idt进行判断。

    (1)如果相等,一般情况下说明文件名都是相同的。
    (2)如果不等,说明CAB中的某些文件有Windows 系统不认可的文件名存在,比如CAB中有XXX.(注意XXX后面的 . )这样的文件名。
    在不相等的情况下,用EXCEL分别打开前面生成的CabFileList.xls和File.idt二个文件,分别对文件名列进行排序,并将File.idt文件的文件名所在列整列复制到CabFileList.xls中的一个新列中,并用IF函数判断二者是否有差异。如图所示(注意Msi_FileTable_FileList列中后面带 . 的文件)。


    7、在提取的文件夹中,将在有差异的文件的文件名后添加一个数字或其他什么,将其改名,然后再从CAB文件中提取有差异的文件的另一个文件。

    8、在CabFileList.xls中插入一个工作表,将第5步中已排序的File.idt 文件的File列和Sequenec 列分别复制到新的工作表中,并在其他列中添加"FILE"、"""、"="等列,然后用CONCATENATE文本合并函数,将这些列中的数据合并成IExpress所需的脚本格式。如图所示。



    9、用汉化好的文件替换已解开的文件(注意:第6、7步中有差异的文件)。
    ※推荐直接汉化已解开的文件,以免重新命名等麻烦。

    10、运行IExpress,选择"仅创建压缩文件"选项(如图),将已用汉化替换的文件全部或部分添加到要打包的文件中,然后选择"在软件包中使用长文件名保存文件"选项,最后保存好.SED扩展名的IExpress脚本文件。





    11、修改IExpress脚本文件。用文本编辑器打开刚才保存的IExpress脚本文件(.sed),并从第8步的EXCEL表中复制SED[Strings] 列到IExpress脚本文件的 [Strings] 节中,同理,复制SED[SourceFiles0] 列到 [SourceFiles0] 节。
    ※重要提示:
    如果第6、7步中有差异文件存在,请在IExpress脚本文件的 [Strings] 节中,将有差异的文件按MSI文件中的文件名命名(在第8步中已经采用了MSI中的文件名列表,所以这里一般不需要修改)。并将IExpress脚本文件的 [SourceFiles0] 节中的文件名全部改为在资源管理器中存在的实际文件名。
    ※备注:
    (1)在一般的IExpress脚本文件(.sed)的[SourceFiles0] 节中的"="号后是没有文件名的。因为有差异文件名存在,所以这里需要特别处理。
    (2)创建CAB时,程序会自动删除[SourceFiles0]节中的所有文件名。请注意保存备份,并在下次创建时复制回去。


    12、再次运行IExpress,打开刚才修改好的IExpress脚本文件,一路下一步,一个已用汉化后文件替换的符合MSI文件中的File表的文件顺序的新CAB文件生成了。

    13、将新的CAB文件插入到MSI文件中。如果是CAB文件独立于MSI,跳过该操作。
      首先,在DOS下或MsiDb.exe快捷方式下,使用"MsiDb.exe -k CAB文件名 -d MSI文件名"命令删除MSI文件中的CAB文件(其实只是清除关联)。然后使用"MsiDb.exe -a CAB文件名 -d MSI文件名"命令插入新的CAB文件到MSI文件中。
    其中:(1)CAB文件名就是Media表中的Cabinet 列中的CAB文件名。注意忽略前置的"#"。
    (2)CAB 和 MSI 文件名均要带后缀扩展名。

    如果提示不成功,请先用"MsiDb.exe -k CAB文件名 -d MSI文件名"命令清除流,然后再用"MsiDb.exe -a CAB文件名 -d MSI文件名"添加新的CAB文件。
    注意:MsiDb.exe 对某些长文件夹名不支持,会提示错误。建议尽量用短文件夹名。 

    14、安装测试。运行一下安装程序,看看是否会在安装过程中出现类似"文件不存在"等错误,如果没有,则大功告成。

    备注


    1、谢谢您阅读,如果本文对您有些帮助,将十分荣幸。
    2、本文版权属wanfu所有,欢迎在保持完整和不修改的条件下转载本文。
    3、联系邮件:z_shangyi@163.com

    关于压缩率

    1、默认情况下,用IEPress制作的CAB文件压缩率相对较低。经初步测试,IEpress的脚本支持Makecab.exe的所有参数,只要在[Options]节中添加CompressionType=lzx一行,就可以实现 lzx 压缩率。
    2、根据 zhfi 网友的提示,查了一下有关资料,用 cabarc.exe -m LZX:21 -r N CAB文件名 "文件所在目录*" 命令确实可以获得比 IEpress 更高的压缩率,而且不存在顺序问题。但是如果有MSI 中有 XXX. 这样的文件,而实际解压后没有了 XXX. 这样的文件,就无法打包成和原始CAB一样的新CAB文件,只能通过修改MSI文件中的File表中的File列中的相关文件名以及在其他表中所关联的文件名才能解决。
    3、根据汉化好友"鱼"的方法,可以在要压缩的文件所在的文件夹下,用以下命令行实现:
    makecab /f <完整路径>MsiFileList.txt /d compressiontype=lzx /d compressionmemory=21 /d maxdisksize=1024000000 /d diskdirectorytemplate=data* /d cabinetnametemplate=data*.cab
    这里:MsiFileList.txt 是指MSI文件中File表中的File列的文件名列表(请按Sequenec 列从小到大排列),
    diskdirectorytemplate=data* 中的 data*,即分卷压缩的情况下,在要压缩的文件所在的文件夹下生成 data1/data2/data3……文件夹,不分卷压缩的情况下,只生成一个文件夹。
    cabinetnametemplate=data*.cab 中的 data*.cab,即分卷压缩的情况下,data1/data2/data3……文件夹中生成data1.cab/data2.cab/data3.cab......等CAB文件名。
    但是,如果有原CAB中有XXX. 和XXX二个解压后文件名相同的文件,那么该方法就不适用了。
    4、如果你已经删除了CAB中的一些文件,并对相关的MSI表进行了修改(如不修改会出现安装错误!),需要缩小MSI文件的话,请使用Orca打开清流后的MSI,然后另存为一个MSI文件,然后用MsiDb.exe插入新的CAB即可。

     

     

     

    注:本文转载自:http://teach.hanzify.org/article/652-1233562028.html

     

     

    补充:压缩cab文件时,文件顺序要按file.idt表中的顺序,否则会出现找不到文件的错误信息。

    替换文件时,文件大小应该会变化,需要使用Orca修改file表中的文件大小。

     

    基本流程:从msi中提取cab文件→使用Orca另存msi文件备用(里面的cab文件应该自行分离,msi文件变小)→解压cab文件→替换文件→压缩cab文件(需要创建sed文件)→修改sed文件中的文件顺序→重新压缩cab文件→将cab文件加入到msi文件

  • 相关阅读:
    021.day21 反射 Class类 反射常用操作
    020.day20 线程概述 多线程优缺点 线程的创建 线程常用方法 生命周期 多线程同步
    019.day19 缓冲流 对象流 标准输入输出流
    018.day18 map集合如何实现排序 File类 IO流 字节流 字符流 编码
    017.day17 Map接口 克隆 treeSet集合排重缺陷
    016.day16 HashSet TreeSet 比较器Comparable Comparator
    015.day15
    014.day14
    013.day13
    线程
  • 原文地址:https://www.cnblogs.com/myzw/p/10784280.html
Copyright © 2011-2022 走看看