【问题标题】:How to extract .msi features from command line?如何从命令行提取 .msi 特征?
【发布时间】:2019-05-12 11:38:37
【问题描述】:

我有一个 .msi,其中包含一些开发文件(gstreamer 开发文件),我想从 .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 中仅提取选定的功能而不将其安装到系统中吗?

【问题讨论】:

  • 添加了一个示例 VBScript,展示了如何以编程方式设置 Feature Level

标签: windows windows-installer


【解决方案1】:

简短回答:进行转换,为要从文件提取中排除的特征设置 Feature Table => Level Column to 0。按如下方式运行管理安装:

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

变换:目前我可能想不到其他方法,但您可以尝试的一种方法是进行您应用的变换行政安装。根据 MSI 中的功能数量,这可能需要大量工作,或者根本不需要太多工作(如果您想要排除的功能很少)。

功能级别:MSI 中有一个特殊之处,即 featureFeature level 设置为 0在管理安装期间不会被提取。这对我来说似乎是一个错误(虽然它是设计使然),但你可以使用它来实现你想要的 - 我认为 - 但它并不完全漂亮。

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

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

工具:您需要一个工具来帮助您进行这种转换。你可能已经有了这个,但对于其他人:我推荐Orca.exe - Microsoft 自己的 SDK 工具。但是,您可以免费使用许多工具。大多数(我认为)在此处进行了描述:How can I compare the content of two (or more) MSI files?(向下滚动到列表底部 - dark.exe 是反编译器而不是 MSI 查看器 - 该链接描述了比较 MSI 文件,而不是更改它们)。

如果您安装了 Visual Studio

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


高级:上面的“比较 MSI”答案中有一个 VBScript (widiffdb.vbs) 链接。它允许比较两个 MSI 文件。还有另一个 VBScript 允许您通过 SQL 语句更新 MSI。见这里:WiRunSQL.vbs。如果您安装了 SDK,您可以在磁盘上找到这些脚本,或者您可以在 github.com 上找到它们。请参阅this answer 底部的脚本使用示例。 如果您有大量功能级别需要设置为 0,请尝试此操作。显然将所有功能设置为 0,然后通过将它们设置回正常(1 或更高 - 取决于 MSI)手动打开您需要的功能。

样机:将所有 Feature levels 设置为 0 的示例 VBScript 代码:

注意!不要在您的主要源 MSI 文件上运行此程序。 复制一份!

此脚本中没有错误处理To generate a transform see sample here(根据原始和修改后的 MSI 文件之间的差异生成转换)。

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"

【讨论】:

    猜你喜欢
    • 2016-05-15
    • 2020-03-20
    • 1970-01-01
    • 2017-08-11
    • 2016-09-12
    • 2019-03-12
    • 1970-01-01
    • 1970-01-01
    • 2018-07-18
    相关资源
    最近更新 更多