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

时间:2009-09-28 03:16:03

标签: c# windows-services installer windows-installer

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

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

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

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

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

4 个答案:

答案 0 :(得分:4)

如果您想沿着编辑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

答案 1 :(得分:2)

答案 2 :(得分:2)

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

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

1   ServiceName 170     1   C__489628C5CC1144CB47F43E8BE7F3F31D

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

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

答案 3 :(得分:0)

在WIX中,通过添加“ ServiceControl”元素来停止安装时的服务,我能够使该服务在升级和卸载之前关闭。这似乎可以解决问题,但是与MSI相关的所有内容都接近黑魔法,因此我当然可以接受任何评论。以下是我的服务组件的定义:

  <Component Id="ServicePrima" Guid="{d0847344-8632-4326-986c-78f4e02a41bb}">
    <ServiceControl Id="ServicePrima_BeforeInstall" Name="ServicePrima" Stop="install" Wait="yes"/>
    <File Name="PrimaPro.ServicePrima.Check.cmd" />
    <File Name="PrimaPro.ServicePrima.exe" Id="ServicePrimaExe" KeyPath="yes" />
    <File Name="PrimaPro.ServicePrima.exe.config" />
    <File Name="PrimaPro.ServicePrima.Install.cmd" />
    <File Name="PrimaPro.ServicePrima.pdb" />
    <File Name="PrimaPro.ServicePrima.Restart.cmd" />
    <File Name="PrimaPro.ServicePrima.SignalRestart.cmd" />
    <File Name="PrimaPro.ServicePrima.Uninstall.cmd" />
    <File Name="PrimaPro.ServicePrima.xml" />
    <ServiceInstall Id="ServicePrima_Install" Name="ServicePrima" DisplayName="PrimaPro - ServicePrima"
                    Type="ownProcess" Start="auto" Interactive="no" ErrorControl="normal"
                    Description="Manages the database synchronization and configuration management of the PrimaPro System and databases on a machine.">
    </ServiceInstall>
    <!-- Do not need to start service here (i.e. attribute Start="install"), the service will be started by "RestartServices" custom action. -->
    <ServiceControl Id="ServicePrima_AfterInstall" Name="ServicePrima" Stop="uninstall" Remove="uninstall" Wait="yes"/>
  </Component>