如何比较两个(或更多)MSI 文件的内容?

How can I compare the content of two (or more) MSI files?

我如何对两个(或更多)MSI 文件 进行“内容比较”并查看文件内部的实际不同之处文件 - 而不是做一个无用的二进制比较? (这显然只告诉我是否正在处理同一文件的副本)。

一些相关的和典型的问题场景


这是一个Q/A-style问题,主题是比较已编译的 MSI 文件以确定 "content differences" 存在哪些真实内容。

Microsoft Orca: If you have Visual Studio installed, try searching for Orca-x86_en-us.msi - under Program Files (x86) - and install it. Then find Orca in the start menu.

  • Current path: C:\Program Files (x86)\Windows Kits\bin.0.17763.0\x86
  • Change version numbers as appropriate

About MSI Files

粗略地说 MSI 文件是 COM-structured 存储文件 - 本质上是文件中的文件系统 - 具有不同的流内容,其中之一是精简的 SQL 服务器数据库(我认为是最通用的术语)。只要MSI文件是可读的,就可以比较(各种格式和类型的)内容。

技术说明:可以想象,触发 System.BadImageFormatException 的 MSI 不 运行 可用(msiexec.exe 不能运行 它),但它可能仍然可读 - 因此具有可比性(如果您遇到过,请添加评论以验证这一点)。

Streams:MSI 中的一些 streamstables with字符串值。也可能有 嵌入式 cab-archives 的流用于存储要部署的文件,并且 table 仅具有 二进制内容 - 例如 Binary table,其中已编译和未编译的自定义操作与设置所需的其他二进制内容一起存储。还有一个特殊的“摘要流”和一个table,图标以其本机二进制格式存储,并且列表还在继续......对于大多数tables 我们可以比较每个 table 中的字符串,就像我们比较 Word 文档(also used to be OLE / COM files - though newer versions now use Open Office XML)中的文本并获得详细的差异报告一样。为了做到这一点,您显然需要一个 special-purpose 工具 来完成这项工作 - 一个能够找到所有相关流的方式的工具。下面列出了一些商业和免费工具。

二进制内容:在详细说明之前,我应该注意比较 Binary TableCabs TableIcon Table 中的内容 - 或任何其他二进制文件 table,通常只允许您进行二进制比较(特别是对于已编译的自定义操作 dll 和 exe 文件)。 编写自定义操作脚本 - 在二进制文件中 table - 可以作为文本进行比较,但编译后的自定义操作只能进行二进制比较。因此,如果您的问题源于编译的自定义操作,您无法在直接比较中真正看到它(您只能看到二进制差异)。 您需要访问您的源代码控制系统以查看哪些代码被用于编译的任何类型的自定义操作 - 希望您有一个良好的标签实践 所以您可以找到每个设置中使用的实际源代码。我不使用这种做法,但对于内部公司版本,也许您甚至可以为编译的自定义操作包含 debug-build dll,并尝试将调试器附加到 运行ning 代码以真正了解出什么事了?不过,我不会在 public 版本中使用调试模式 dll - 除非我澄清了任何风险。调试代码可能充满(意想不到的)调试消息框(用作附加调试器的入口点)和其他永远不应出现在生产包中的问题。

想想看,通过使用 dark.exe 反编译 MSI 文件的技术,您的 cab 文件和图标文件绝对可以与旧(或新)MSI 文件中的相应版本进行比较 - 这是如下面所描述的。然后,使用一个好的比较工具(下面提到了 Beyond Compare),您可以对不同 MSI 版本之间的 cab 文件内容进行完整的比较(有些文件可能是文本文件,可以进行文本比较)。我猜 cabs 和图标是开放格式的 "transparent binaries" 而不是编译的二进制文件(带有自定义操作等),后者本身不可反编译或 inspectable (除非您知道如何反编译托管二进制文件).

结论MSI 文件是完全透明的,除了已编译的自定义操作 . This transparency is one of the core benefits of MSI. Most Windows Installer benefits, over previous deployment technologies, generally center around corporate deployment benefits. Unfortunately developers may only see the bad aspects of MSI: the (potential) MSI anti-patterns(朝向底部 - 非常混乱,目前 ad-hoc)。不可否认,其中一些问题非常严重并且违反了 "the principle of least astonishment"。开发人员 - 为什么还有其他同样重要的事情要做 - 坦率地说,他们可能会难以置信地摸不着头脑。

请不要误会:MSI 具有巨大的企业部署优势(see same link as above, towards bottom). Condensed: reliable silent running, remote management, rollback, logging, implicit uninstall feature, elevated rights, standardized command line, transparency, transforms for standardized setup customization and admin install to reliably extract files. Just to name the big ones quickly. Benefits in list form here

到目前为止有很多题外话 - 让我们进入正题。可以使用哪些工具来比较 MSI 文件?


Commercial Tools

一些商业部署工具例如Installshield, Advanced Installer and many other MSI tools支持查看和比较MSI文件。也许我添加了太多 link,但让我使用我通常的 "if you link to one, you link to everyone" 策略 - 它应该可以节省一些时间和一些 Google 搜索。

作为特别说明 - 怀旧的 - 我见过的最好的 MSI-diff 功能是在 Wise Package Studio 中。老实说,它比其他产品高出一头 - 始终有效,颜色编码整齐,易于理解。此工具不再销售,如下所述:What installation product to use? InstallShield, WiX, Wise, Advanced Installer, etc(如果您的公司中有打包团队,也许他们有备用许可证?)。


Free Tools

商业工具很好,但也有 几个免费的替代品 可用于比较 MSI 文件 - 下面是其中一些的列表以及如何使用每个工具的一些提示(在一种相当简约的方式)。

dark.exe 添加了更多详细信息 - 这根本不是 COM-structured 存储文件的比较工具,而是一种将 MSI 文件反编译为 WiX XML 源的方法文件并提取所有支持文件(图标、二进制文件、cab、安装文件)- 之后可以将它们与常规文本/二进制比较工具进行比较。

1。 Orca(MSI SDK)

微软自己的MSI SDK工具/查看器Orca可以查看和编辑MSI文件,但是没有直接支持比较两个 MSI 文件(据我所知)。我想您可以导出 table 然后比较它们,但其他工具具有更多 built-in 功能。提到此选项是因为您可能已经安装了 Orca,这可能是完成简单差异的快速方法。 “穷人的选择”。

您可能已经有了安装程序。如果您安装了 Visual Studio,请尝试搜索 Orca-x86_en-us.msi - 在 Program Files (x86) 下 - 然后安装它。然后在开始菜单中找到Orca。从技术上讲,Orca 是作为 the Windows SDK 的一部分安装的(很大,但可以免费下载)。如果您没有安装 Visual Studio,也许您认识安装了的人?只需让他们搜索此 MSI 并发送给您(这是一个很小的半 mb 文件)- 他们应该花几秒钟的时间。如果没有,您可以随时下载 Windows SDK

2。 Super Orca(free third party tool)

Super Orca 将允许对两个 MSI 文件进行基本比较。我的冒烟测试似乎表明可能会忽略诸如摘要流之类的高级字段。换句话说,直接 table 仅进行比较。可能还有其他限制。也许它已经足够好了?简单易用。

注意:我无法确定,但我相信这个工具在没有警告的情况下保存了我的 MSI 一次。这在当时是非常不受欢迎的。

3。 widiffdb.vbs(MSI SDK)

MSI SDK 有一个 VBScript,您可以使用它来查看两个 MSI 文件之间的差异。它被称为 widiffdb.vbs (msdn)。使用此工具,我可以看到 Super Orca 忽略的 Summary Stream 差异。任何MSI SDK都是权威的

UPDATE: All MSI SDK API scripts on github.com (the actual VBScript code).

  • 比较 MSI 文件需要添加 link 到 the full list of such MSI SDK VBScripts - for various purposes. Don't be confused, only widiffdb.vbs,但可以找到许多用于其他目的的有用脚本。
  • 如果您安装了 Visual Studio,只需搜索 widiffdb.vbs。使用 cscript.exe 启动并传入两个 MSI 文件的完整路径以比较它们。在控制台中输出。

用法:

cscript.exe widiffdb.vbs "Setup 1.msi" "Setup 2.msi"

示例输出:

Property Value           [ALLUSERS] {1}->{2}
Property Value           [MSIINSTALLPERUSER] {}->{1}
Property INSERT          [MSIINSTALLPERUSER]
[=11=]5SummaryInformation   [9] {{00000000-0000-0000-0000-000000000000}}->{{00000000-0000-0000-0000-000000000001}}
[=11=]5SummaryInformation   [12] {28.03.2019 15:20:02}->{28.03.2019 14:40:52}
[=11=]5SummaryInformation   [13] {28.03.2019 15:20:02}->{28.03.2019 14:40:52}
[=11=]5SummaryInformation   [15] {2}->{10}

如果安装了 Visual Studio,您可以在 Program Files (x86) 下搜索脚本(它是 Windows SDK 也将与 Visual Studio 一起安装)-(当前路径是:C:\Program Files (x86)\Windows Kits\bin.0.17763.0\x86 - 只需适当地替换版本号,您应该找到MSI 更快)。

4。 dark.exe(WiX toolkit - open source)

dark.exe binary from the WiX toolset(可能用于编译某些 MSI 文件的工具包)。此 dark.exe 是 MSI 文件的 "disassembler" 或 "decompiler"。它会将 MSI 文件转换为 wxs XML 格式(WiX 自己的格式首先用于编译 MSI 文件),以及一些提取的二进制文件(如果您使用正确的反编译选项和标志).

wxs 源文件可以作为常规文本源文件进行比较(我最喜欢的工具是 Beyond Compare,但它是一个商业工具 - 有很多文本比较工具 - 包括Visual Studio 中的那些)。二进制文件显然可以进行二进制比较。例如,任何提取的 CAB 文件都可以与来自另一个 MSI 安装版本的另一个类似的 cab 文件进行比较。

这是一个示例命令行:

dark.exe -x outputfolder MySetup.msi
  • 在许多情况下,这将对 MSI 文件进行很好的比较,您应该能够确定真正不同的地方。

  • 提取的二进制文件可以是脚本文件(VBScripts 等)或任意数量的其他二进制文件(例如已编译的 DLL 自定义操作)。在后一种情况下,您无法进一步反编译它 - 除非它是 .NET 二进制文件并且您具有反编译此类二进制文件的专业知识。

  • 但是,应该注意 WiX-generated 使用完全相同的 WiX 源文件编译的 MSI 文件可能会有所不同,原因如下:

    • 同一个 WiX 源文件也可以用 不同的 compiler and linker settings, and this can affect the generated MSI file in several different ways. To see all switches, download and install WiX 编译,只需将 candle.exelight.exe 写入命令提示符即可点击 enter.

    • 某些字段,例如 package GUIDsproduct GUIDs 可以设置为 [= wxs文件中的320=]。结果,生成的 MSI 文件中的相应字段将明显不同在这种情况下的每个构建。

      • 目前我还没有可以将哪些字段设置为 auto-generate 的完整列表(如果您知道,可以点击编辑并在原位修改)。

      • 提到的 auto-generated 字段也可以是 hard-coded(这对包 GUID 不利,但这是另一个长篇故事 - 只要知道如果你找到两个具有相同包 GUID 的二进制不同的 MSI 文件,那么你就有大麻烦了 - 如果它们在野外 - Windows 安装程序将根据定义将它们视为相同的文件)。包裹代码应始终为 auto-generated。题外话.

    • MSI 文件本身显然有不同的文件日期信息,这些信息是单独编译的——只是为了说明这一点。

还有一条与手头的主题有些无关但仍然很重要的特别说明:您可以使用 dark.exe 反编译使用 WiX 的 Burn 功能编译的 executables。这是 WiX 的 引导程序功能 用于按顺序安装一个或多个 MSI 和/或 EXE 文件 - 一个接一个。这些引导程序是 EXE 文件,您可以将它们解压缩到它们的组成 MSI and/or EXE 文件中:

dark.exe -x outputfolder setup.exe

只需打开命令提示符,CD 到 setup.exe 所在的文件夹。然后指定上面的命令。具体示例:dark.exe -x outputfolder MySetup.exe。输出文件夹将包含几个 sub-folders,其中包含提取的 MSI 和 EXE 文件以及 Burn GUI 的清单和资源文件。然后可以如上所述反汇编任何 MSI 文件以生成 WiX 源文件 (wxs)。

5。 InstEd(free third party tool - with plus version available)

出于某种原因,我从来没有主动使用过这个工具,但测试了几次。再次测试它似乎确实完成了比较两个 MSI 文件的工作,尽管来自一个奇怪的菜单选项(这让我认为该功能以前不起作用)。

  • 打开一个 MSI,然后转到 Transform => Compare Against... 并浏览到要与第一个比较的 MSI。
  • 比较似乎没问题,我看到摘要流中有变化 - 例如 - 但 diff 似乎没有显示不同之处(除非我没有看到它)。
  • 要查看摘要流更改,请在单独的 InstEd 实例中打开两个文件,然后在两个实例中转到 Tables => Summary Info...。现在比较 属性 表格中的信息。或者使用上面列出的 widiffdb.vbs 脚本。

6. Other Tools...(COM-structured storage file viewers)

毫无疑问,还有许多其他工具能够查看 COM-structured 存储文件,但我认为以上选项对于大多数用户来说应该足够了。我将再次添加 link 到 installsite.org's list of MSI tools

7。 Advanced Installer(commercial tool with some free features)

即使没有 运行 完整许可,此商业工具也可以用作查看器并允许对 MSI 文件进行一些基本操作。好的一点是你甚至不需要使用原始的 tables,而是可以使用更好的用户界面来 "hotfix" MSI 中的各种东西。例如各种升级参数(主要升级卸载失败时继续或失败等...)。

Table 编辑器视图(straight-up table 视图)中所做的更改在其他 "wizard views". The reason for this is explained here.


链接