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

C# 如何停止Windows服务进行升级安装?,c#,windows-services,installation,windows-installer,C#,Windows Services,Installation,Windows Installer,我使用VisualStudio2008开发了一个Windows服务和一个安装项目。当我进行升级安装时,会收到以下警告: 以下应用程序正在使用安装程序必须更新的文件。您可以关闭应用程序并单击“重试”,或单击“继续”,以便安装程序继续安装,并在系统重新启动时替换这些文件 我想在升级安装期间停止Windows服务。我已尝试创建自定义操作并重写OnBeforeInstall方法,但是在出现警告弹出消息后调用该方法太迟 作为msi安装程序的一部分,是否有任何方法可以实现这一点。我希望在执行msi安装程序之

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

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

我想在升级安装期间停止Windows服务。我已尝试创建自定义操作并重写OnBeforeInstall方法,但是在出现警告弹出消息后调用该方法太迟

作为msi安装程序的一部分,是否有任何方法可以实现这一点。我希望在执行msi安装程序之前,不必将此作为单独的任务来执行

更新:

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

查看:

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

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

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


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

如果您想继续编辑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

在WIX中,我可以通过添加“ServiceControl”元素在安装时停止服务,从而在升级和卸载之前关闭服务。这似乎做的工作,但一切有关微星是接近黑魔法,所以我当然愿意接受任何意见。以下是我的服务组件的定义:

  <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>


能否从安装程序执行shell命令?如果是这样,您可以运行netstopservicename作为杀死它的首要任务之一。Ug,不要这样做。Windows Installer本机支持停止/启动服务。只需使用ServiceControl表。