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



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

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

msiexec /i gstreamer.msi /qb TARGETDIR=somefolder ADDLOCAL=_gstreamer_1.0_system,_gstreamer_1.0_libav

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

msiexec /a gstreamer.msi /qb TARGETDIR=somefolder ADDLOCAL=_gstreamer_1.0_system,_gstreamer_1.0_libav

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

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

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

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

功能级别 :MSI有一个特殊之处,即功能级别设置为0特性将不会在管理安装期间提取。对我来说,这似乎是一个bug(不过是设计出来的(,但你可以在这里用它来实现你想要的——我认为——但它并不漂亮。

  1. 变换 :对所有不想提取的特征进行变换,将"特征"表中的"级别"列设置为0
  2. msiexec.exe :通过以下命令行将转换应用于MSI:

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

工具 :您需要一个工具来帮助您进行此转换。你可能已经有了,但对于其他人:我推荐Orca.exe-微软自己的SDK工具。但是,您可以免费使用许多工具。这里描述了大多数(我认为(:如何比较两个(或多个(MSI文件的内容?(向下滚动到列表底部-dark.exe是一个反编译器,而不是MSI查看器-链接描述了比较MSI文件,而不是更改它们(。

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


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

实体模型 :将所有Feature levels设置为0的示例VBScript代码:

注意 请勿在主源MSI文件上运行此操作复制

此脚本中没有错误处理。要生成转换,请参阅此处的示例(根据原始和修改后的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"

相关内容

  • 没有找到相关文章

最新更新