如何从命令行提取 .msi 功能?

How to extract .msi features from command line?

我有一个包含一些开发文件(gstreamer 开发文件)的 .msi,我想从 .msi 中提取一些功能到某个文件夹,而不是从命令行安装。

我知道如何使用 msiexec 的 ADDLOCAL 属性 安装一些功能:

msiexec /i gstreamer.msi /qb TARGETDIR=some\folder ADDLOCAL=_gstreamer_1.0_system,_gstreamer_1.0_libav

但是当我试图在不使用管理安装的情况下提取文件时,ADDLOCAL 属性 似乎不起作用并且它提取了包中的所有文件:

msiexec /a gstreamer.msi /qb TARGETDIR=some\folder ADDLOCAL=_gstreamer_1.0_system,_gstreamer_1.0_libav

有人知道如何只从 .msi 中提取选定的功能而不将其安装到系统中吗?

Short Answer: Make a transform, set Feature Table => Level Column to 0 for features you want to exclude from file extract. Run administrative installation as follows:

msiexec.exe /a MySetup.msi TRANSFORMS=MyTransform.mst TARGETDIR=C:\MyExtractPath\

Transform:可能还有其他方法我暂时想不到,但是你可以尝试的一种方法是进行应用于管理安装的转换。根据 MSI 中功能的数量,这可能需要大量工作,也可能根本不需要太多工作(如果您想要排除的功能很少)。

功能级别:MSI 中有一个特点,即 feature that has its Feature level 设置为 0 在管理安装过程中不会被提取。这对我来说似乎是一个错误(虽然它是设计使然),但您可以使用它来实现您在这里想要的东西 - 我认为 - 但它并不十分漂亮。

  1. Transform:进行转换,将 Feature table 中的 Level 列设置为 0不想提取。
  2. msiexec.exe:通过命令行将转换应用到 MSI,如下所示:

    msiexec.exe /a MySetup.msi TRANSFORMS=MyTransform.mst TARGETDIR=C:\MyExtractPath\
    

工具:您需要一个工具来帮助您进行此转换。你可能已经有了这个,但对于其他人:我推荐 Orca.exe - Microsoft's own SDK tool. However, there are a number of tools you can use that are free. The majority (I think) are described here: (向下滚动到列表底部 - dark.exe 是一个反编译器而不是 MSI 查看器 - link 描述了比较 MSI 文件,不改变它们)。

Orca.exe 如果您安装了 Visual Studio 将已经在磁盘上(很可能)。尝试在 Program Files (x86) 下搜索 Orca-x86_en-us.msi。只需安装它并在开始菜单中找到 Orca(或搜索它)。


高级: 有一个VBScript (widiffdb.vbs) linked 在上面的 "compare MSI" 答案中。它允许比较两个 MSI 文件。还有另一个 VBScript 允许您通过 SQL 语句更新 MSI。参见此处:WiRunSQL.vbs. These scripts you can find on disk if you have the SDK installed, or you can find them on github.com. See sample use of the script towards the bottom in 如果要将大量功能级别设置为 0,请尝试此操作。显然将所有功能设置为 0,然后通过将它们设置回正常(1 或更高 - 取决于 MSI)来手动打开您需要的功能。

Mockup:示例 VBScript 代码以将所有 Feature levels 设置为 0:

Note! Do not run this on your main source MSI file. Make a copy!

No error handling in this script. To generate a transform see sample here (generate transform based on diff between original and modified MSI file).

Const msiOpenDatabaseModeTransact = 1
Const msiViewModifyReplace = 4

Set installer = CreateObject("WindowsInstaller.Installer")
Set database = installer.OpenDatabase("Test.msi", msiOpenDatabaseModeTransact)

' Allow user to cancel operation
If MsgBox ("Only run this on a COPY of your MSI!" & vbNewLine & vbNewLine & "Continue?", vbYesNo + vbInformation, "Warning!") = vbNo Then
   MsgBox "Update Aborted.", vbOKOnly + vbInformation, "Aborted" 
   WScript.Quit(0)
End If

sql = "SELECT * FROM `Feature`"
Set view = database.OpenView(sql)
view.Execute()

Do
   Set record = view.Fetch()
   If record Is Nothing Then Exit Do
   record.IntegerData(6) = 0
   view.Modify msiViewModifyReplace, record
Loop

view.Close()
database.Commit()

MsgBox "Update Complete.", vbOKOnly + vbInformation, "Completed"