如何在MSI安装程序中替换文件?

时间:2020-03-06 14:39:19  来源:igfitidea点击:

我想替换一个msi中的单个文件。怎么做?

解决方案

我们需要使用MsiDB.exe(Windows Installer SDK随附)从msi中提取CAB文件流。从命令行使用-x选项运行它,并指定在msi数据库的"媒体"表中列出的cab文件的名称。

或者,如果我们在VSI选项中将"压缩文件为:"选项指定为"机柜文件中的压缩文件",以使cab文件在生成时不被msi占用,则可以跳过此部分(将在同一目录中创建作为msi)。

提取后,我们可以在cab文件夹中更改指定的文件,其名称已被修改,因此我们需要在文件表中找出该文件的msi名称,然后将新文件重命名为该文件。

完成后,我们可以使用-a选项使用MsiDB实用程序将其弹出。

在添加-a之前,我们需要使用msidb -k从MSI中删除cab。

最简单的方法是重新打包MSI:

  • 在Wise for Windows Installer中打开MSI文件。选择一个选项以提取文件。
  • 在磁盘上找到文件并替换它。
  • 建立MSI。

这些步骤也应适用于InstallShield。

非常简单的示例代码,用于替换MSI中的文件。这不会将新文件/ CAB流回MSI,但要求CAB与MSI位于同一目录中才能成功安装。我敢肯定,我们可以多做一些改动,以更改代码以流回CAB。

Const MSI_SOURCE = "application.msi"
Const FILE_REPLACE = "config.xml"

Dim filesys, installer, database, view
Dim objFile, size, result, objCab

Set filesys=CreateObject("Scripting.FileSystemObject")
Set installer = CreateObject("WindowsInstaller.Installer")
Set database = installer.OpenDatabase (MSI_SOURCE, 1)

Set objFile = filesys.GetFile(FILE_REPLACE)
size = objFile.Size

Set objCab = CreateObject("MakeCab.MakeCab.1")
objCab.CreateCab "config.cab", False, False, False
objCab.AddFile FILE_REPLACE, filesys.GetFileName(FILE_REPLACE)
objCab.CloseCab

Set view = database.OpenView ("SELECT LastSequence FROM Media WHERE DiskId = 1")
view.Execute

Set result = view.Fetch
seq = result.StringData(1) + 1 ' Sequence for new configuration file

Set view = database.OpenView ("INSERT INTO Media (DiskId, LastSequence, Cabinet) VALUES ('2', '" & seq & "', 'config.cab')")
view.Execute

Set view = database.OpenView ("UPDATE File SET FileSize = " & size & ", Sequence = " & seq & " WHERE File = '" & LCase(FILE_REPLACE) & "'")
view.Execute