从 EXE 更新已安装的 MSI 版本
Update Installed MSI Version from EXE
我创建了一个通过 MSI 安装的应用程序,版本号为 X.X.X - 比方说 1.0.0。接下来,我们创建了一个不使用任何形式的 MSI 的自定义自我更新过程。 (我们正在通过代码替换文件。)这个自定义的自我更新过程是必需的,它使我们能够远程快速地管理大量用户。 运行 我们已经有一段时间了。困扰我的一件事是我们应用程序的“程序和功能”屏幕上显示的版本仍然是 1.0.0。有没有办法从主可执行文件更新程序版本?
您正在尝试重新发明补丁。 Windows 安装程序不支持此功能,无法执行您想要执行的操作。
更新:Tao of the Windows Installer, Part 2
Rule 21: Avoid Using Configuration Data You Don’t Own
As part of the initial design for the Installer, the consistency of
installations was achieved via Microsoft taking ownership of the code
for the install engine. This includes the location and format of all
configuration data. This data is managed by the Installer and direct
access by users or applications is discouraged; in fact some of the
data is encoded to make it very difficult to manipulate manually.
You should not try to peek directly into Windows Installer
configuration information. Instead, use the Windows Installer API to
get the information you need. Accessing the data this way ensures that
your package or application will continue to work even if the
underlying configuration data changes location or format.
在这种情况下 API 是 MsiGetProductInfo function. This function returns INSTALLPROPERTY_VERSIONSTRING
which is which is the ProductVersion property. This API has no mechanism to set the ProductVerion because MSI does this internally during PublishProduct Action。如果您查看注册表,您会在 HKCR\Installer\Products\PackedGuid\Version 下找到它。 Packed Guid 是您的产品代码的 "Darwin transform",采用 DWORD 格式。 ProductVersion 以 DWORD 格式存储,1 个字节用于 Major,1 个字节用于 Minor,2 个字节用于构建。这是因为 ProductVersion 忽略了第 4 个字段,尽管它存储在 ARP 中。
这个注册表结构被混淆以试图鼓励规则 21。不要在进程之外弄乱 Windows 安装程序配置数据。让微星来处理。
可以通过修改位于两个位置之一的已安装应用程序的注册表值来更新 MSI 安装版本。在我的 Windows 8 PC 上,它位于以下位置:
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{MSI-GUID}
它也可能位于:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{MSI-GUID}
要更新“程序和功能”屏幕上显示的版本号,请修改注册表值 "DisplayVersion"
为了更好的可读性,将评论改为答案,并针对您的问题和相关环境讨论事实:
首先让我们看看您关于更改
中 DisplayVersion
值的提议
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{MSI ProductCode}
对于 32 位 MSI 设置(大多数设置仍然在这里运行,通常即使包含 64 位或独立(例如 .NET)代码,但这是另一回事)或
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{MSI ProductCode}
用于 64 位 MSI 设置。首先,这只是机器范围 ("LOCAL_MACHINE") 设置的地方,而不是用户相关设置的地方,但没关系,因为这是标准的。
编辑 DisplayVersion 不是最佳做法。至少,它可以受到讨论,如果要编辑它。事实上,它是一个免费的字符串,许多设置都在使用它,称其版本不是“1.0”,而是 "V1.0" 或“1.0a”或类似的。
如果这样做,在 msi 本身(最后)的自定义操作中执行它是最糟糕的。
至少,作为反对那些称禁止更改此键的人的论据:这不是 MSI 逻辑上使用版本操作的地方,此版本不用于版本比较。实际上它只是一个输出字符串。
OTOH,原始设置 (MSI) 可以再次覆盖它 repair/update/reinstall。所以警告不要手动更改是有背景的。
另外:
有 Windows 版本,尤其是较旧的版本,存在更新问题,因此更改注册表值不会立即反映在控制面板视图中。例如,有一个 ARP 缓存保存所有安装条目。我不认为 Windows 7 或更高版本会出现这些问题,但过去看到过问题并且知道 ARP 缓存仍然存在让我在这里保持谨慎。
我推荐的,我称之为好的做法,是不要更改此号码,但让它属于本机 MSI。
Instad 让 MSI 设置对控制面板中的用户不可见("Programs and Features" 或 ARP 由于它的旧名称,我们在 MSI 和设置社区中仍然这样称呼它) :
要么将您的 MSI 修复程序中的 ARPSYSTEMCOMPONENT
属性 设置为 1(通常为十六进制 1,但因为是您,您只能选择十进制 1 :-))。
或者在安装时将 ARPSYSTEMCOMPONENT=1
作为命令行参数提供给您想要的任何 MSI 设置。
事实上,这也是 Microsoft 对 SQL 服务器、Visual Studio、Office 设置所做的。它们由多个设置组成,这些设置应像不可见(设置)组件一样运行。
或者您可以进行(任何)MSI 设置 "invisible" 安装后 :只需更改注册表中的注册表值 SystemComponent
(或添加)直接到 1 。
但这又是不干净的,因为修复、更新或重新安装可能会再次改变它。但它不会破坏任何东西——最坏的情况是不可见的设置会变得可见。
然后您为可视 ARP 设置构建另一个设置(可能是 "main" 设置),或者您只是在注册表中上述 "Uninstall" 键下创建一个完整的 MSI 独立键。 (在程序中或在 "normal" MSI 设置中)。这可以是 GUID 或普通名称。查看您的注册表,您会发现许多非 GUID 示例,例如通过 Adobe 等。每个非 GUID 都不是 "Windows Installer" (MSI) 设置,但当然也有一些类似 GUID 的条目可以通过非 MSI 设置。
主要优点是:这个新的DisplayVersion
在MSI独立键中可以自己控制。
我创建了一个通过 MSI 安装的应用程序,版本号为 X.X.X - 比方说 1.0.0。接下来,我们创建了一个不使用任何形式的 MSI 的自定义自我更新过程。 (我们正在通过代码替换文件。)这个自定义的自我更新过程是必需的,它使我们能够远程快速地管理大量用户。 运行 我们已经有一段时间了。困扰我的一件事是我们应用程序的“程序和功能”屏幕上显示的版本仍然是 1.0.0。有没有办法从主可执行文件更新程序版本?
您正在尝试重新发明补丁。 Windows 安装程序不支持此功能,无法执行您想要执行的操作。
更新:Tao of the Windows Installer, Part 2
Rule 21: Avoid Using Configuration Data You Don’t Own
As part of the initial design for the Installer, the consistency of installations was achieved via Microsoft taking ownership of the code for the install engine. This includes the location and format of all configuration data. This data is managed by the Installer and direct access by users or applications is discouraged; in fact some of the data is encoded to make it very difficult to manipulate manually.
You should not try to peek directly into Windows Installer configuration information. Instead, use the Windows Installer API to get the information you need. Accessing the data this way ensures that your package or application will continue to work even if the underlying configuration data changes location or format.
在这种情况下 API 是 MsiGetProductInfo function. This function returns INSTALLPROPERTY_VERSIONSTRING
which is which is the ProductVersion property. This API has no mechanism to set the ProductVerion because MSI does this internally during PublishProduct Action。如果您查看注册表,您会在 HKCR\Installer\Products\PackedGuid\Version 下找到它。 Packed Guid 是您的产品代码的 "Darwin transform",采用 DWORD 格式。 ProductVersion 以 DWORD 格式存储,1 个字节用于 Major,1 个字节用于 Minor,2 个字节用于构建。这是因为 ProductVersion 忽略了第 4 个字段,尽管它存储在 ARP 中。
这个注册表结构被混淆以试图鼓励规则 21。不要在进程之外弄乱 Windows 安装程序配置数据。让微星来处理。
可以通过修改位于两个位置之一的已安装应用程序的注册表值来更新 MSI 安装版本。在我的 Windows 8 PC 上,它位于以下位置:
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{MSI-GUID}
它也可能位于:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{MSI-GUID}
要更新“程序和功能”屏幕上显示的版本号,请修改注册表值 "DisplayVersion"
为了更好的可读性,将评论改为答案,并针对您的问题和相关环境讨论事实:
首先让我们看看您关于更改
中DisplayVersion
值的提议
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{MSI ProductCode}
对于 32 位 MSI 设置(大多数设置仍然在这里运行,通常即使包含 64 位或独立(例如 .NET)代码,但这是另一回事)或
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{MSI ProductCode}
用于 64 位 MSI 设置。首先,这只是机器范围 ("LOCAL_MACHINE") 设置的地方,而不是用户相关设置的地方,但没关系,因为这是标准的。
编辑 DisplayVersion 不是最佳做法。至少,它可以受到讨论,如果要编辑它。事实上,它是一个免费的字符串,许多设置都在使用它,称其版本不是“1.0”,而是 "V1.0" 或“1.0a”或类似的。 如果这样做,在 msi 本身(最后)的自定义操作中执行它是最糟糕的。
至少,作为反对那些称禁止更改此键的人的论据:这不是 MSI 逻辑上使用版本操作的地方,此版本不用于版本比较。实际上它只是一个输出字符串。
OTOH,原始设置 (MSI) 可以再次覆盖它 repair/update/reinstall。所以警告不要手动更改是有背景的。
另外: 有 Windows 版本,尤其是较旧的版本,存在更新问题,因此更改注册表值不会立即反映在控制面板视图中。例如,有一个 ARP 缓存保存所有安装条目。我不认为 Windows 7 或更高版本会出现这些问题,但过去看到过问题并且知道 ARP 缓存仍然存在让我在这里保持谨慎。
我推荐的,我称之为好的做法,是不要更改此号码,但让它属于本机 MSI。
Instad 让 MSI 设置对控制面板中的用户不可见("Programs and Features" 或 ARP 由于它的旧名称,我们在 MSI 和设置社区中仍然这样称呼它) :
要么将您的 MSI 修复程序中的 ARPSYSTEMCOMPONENT
属性 设置为 1(通常为十六进制 1,但因为是您,您只能选择十进制 1 :-))。
或者在安装时将 ARPSYSTEMCOMPONENT=1
作为命令行参数提供给您想要的任何 MSI 设置。
事实上,这也是 Microsoft 对 SQL 服务器、Visual Studio、Office 设置所做的。它们由多个设置组成,这些设置应像不可见(设置)组件一样运行。
或者您可以进行(任何)MSI 设置 "invisible" 安装后 :只需更改注册表中的注册表值 SystemComponent
(或添加)直接到 1 。
但这又是不干净的,因为修复、更新或重新安装可能会再次改变它。但它不会破坏任何东西——最坏的情况是不可见的设置会变得可见。
然后您为可视 ARP 设置构建另一个设置(可能是 "main" 设置),或者您只是在注册表中上述 "Uninstall" 键下创建一个完整的 MSI 独立键。 (在程序中或在 "normal" MSI 设置中)。这可以是 GUID 或普通名称。查看您的注册表,您会发现许多非 GUID 示例,例如通过 Adobe 等。每个非 GUID 都不是 "Windows Installer" (MSI) 设置,但当然也有一些类似 GUID 的条目可以通过非 MSI 设置。
主要优点是:这个新的DisplayVersion
在MSI独立键中可以自己控制。