如何停止Windows服务进行升级安装?

我使用Visual Studio 2008开发了一个Windows服务和一个安装项目。当我进行升级安装时,我收到以下警告:

以下应用程序正在使用安装程序必须更新的文件。 您可以关闭应用程序并单击“再试一次”,或单击“继续”以使安装程序继续安装,并在系统重新启动时替换这些文件。

我想在升级安装期间停止Windows服务。 我已经尝试创建一个自定义操作并重写OnBeforeInstall方法,但是在警告弹出消息已经发生后,这会被调用得太晚。

有没有办法在msi安装程序中完成此操作。 在执行msi安装程序之前,我宁愿不必将此作为单独的任务执行。

更新:
根据进一步的研究,我发现MSI数据库支持这一点,但内置的Visual Studio安装程序(安装程序)项目并没有提供这样做的方法。 必须调整MSI数据库,或者使用WiX或商业安装程序。

请注意: 升级Windows服务而不卸载

如果您想沿着编辑MSI ServiceControl表的路线走下去,以下VBS脚本对我有用:

Dim installer, database, view, result Set installer = CreateObject("WindowsInstaller.Installer") Set database = installer.OpenDatabase ("Installer.msi", 1) Set view = database.OpenView("INSERT INTO ServiceControl (ServiceControl,Name,Event,Arguments,Wait,Component_) VALUES ('ServiceName','ServiceName',170,null,null,'C__751A71A3822A287367770DB29839A759')") view.Execute database.Commit Set database = nothing 

它已经内置到MSI / Windows Installer中…唯一的问题是.NET安装程序类不使用MSI“服务安装”function。 实际发生的是MSI正在尝试使用刚刚复制的文件安装文件并运行自定义命令(即所有Visual Studio都放入MSI)。

要解决此问题,您可以使用ORCA编辑MSI并将以下行添加到ServiceControl表:

 1 ServiceName 170 1 C__489628C5CC1144CB47F43E8BE7F3F31D 

您可以从FILES表中查找的组件ID …我只选择了主EXE文件的组件ID。 170是一个位图,告诉Windows Installer在安装和卸载时停止并删除该服务。

这将清除.NET安装程序添加服务的道路,您可以使用ServiceController在通过自定义命令安装服务后启动该服务。

在WIX中,我可以通过添加“ServiceControl”元素来在升级和卸载之前使服务关闭,以便在安装时停止服务。 这似乎可以完成这项工作,但与MSI相关的一切都接近黑魔法,所以我肯定对任何评论持开放态度。 以下是我的服务组件定义为: