【问题标题】:upgrade a service using MSI installer使用 MSI 安装程序升级服务
【发布时间】:2026-02-13 13:30:02
【问题描述】:

我正在使用 MSI 安装程序升级我的自定义 Windows 服务。我正在使用 C# 代码启动 MSI 进程,首先卸载服务,然后安装新版本。

我需要确保在 MSI 开始安装新版本之前,之前的版本已被卸载。如何在 c# 中添加此检查?

【问题讨论】:

  • 如果您在 Visual Studio 中使用setup extension,在安装新应用/服务之前,将执行卸载之前的应用/服务的操作
  • 你应该说你正在使用什么工具。 VS 安装项目使用安装程序类,其他工具使用内置的 Windows Installer 功能。
  • 我正在使用 InstallSheild.. 这个问题是因为当 MSI 可以从注册表中删除服务时,我的代码开始安装它的新版本。因此 MSI 确实从机器注册表中删除了该服务,但由于此过程中的时间滞后,新版本安装失败。为了解决这个问题,我现在使用 sc query servicename 在安装之前检查服务是否存在,所以当服务存在时我正在做thread.sleep(1000)

标签: c# windows-installer


【解决方案1】:

我建议使用 WIX 来执行此操作。 MSI http://wixtoolset.org/documentation/

的封装

确保作为最佳做法增加版本。

关键是增加版本属性设置 AllowSameVersionUpgrades="yes" 而不是更改 UpgradeCode="[your unique upgradecode here]"。确保 UpgradeCode 属性保持不变,它必须是静态的,因此不应设置为 *,这将生成随机 GUID。

<MajorUpgrade AllowSameVersionUpgrades="yes" DowngradeErrorMessage="A newer version of [ProductName] is already installed." />

 <Product
Name="Sample"
Id="*"
UpgradeCode="4c79fec3-a6b7-46eb-90d6-46688a7f1662"
Manufacturer="Sample"
Version="0.1.3.0"
Language="1033"> ... />

你的问题是如何在 C# 中做到这一点

检查注册表项 HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\

SC QUERY 您可能只想用 C# 代码替换该部分。我强烈建议不要使用大多数内置的 Windows 命令行程序。

【讨论】:

    【解决方案2】:

    我正在使用 InstallSheild.. 发生此问题是因为当 MSI 安装程序可以从注册表中删除 SERVICE 时,我的代码开始安装它的新版本。

    所以MSI 确实从机器注册表中删除了该服务,但由于此过程中的时间滞后,新版本安装失败。这主要发生在服务器机器上。不知道是什么原因。

    为了解决这个问题,我现在使用sc query servicename 在安装前检查服务是否存在,所以服务存在时我正在做thread.sleep(1000)

    如果有的话,请分享一个更好的方法。但我只能使用 InstallSheild 来完成。

    【讨论】: