如何卸载Windows服务并删除其文件而不重新启动

时间:2008-11-18 18:06:44

标签: windows scripting windows-services operating-system filesystems

我当前的项目涉及部署作为Windows服务运行的升级后的.exe文件。为了用新版本覆盖现有的.exe,我目前需要:

  1. 停止服务
  2. 卸载服务
  3. 重新启动系统(因此Windows会释放它对文件的保留)
  4. 部署新的.exe
  5. 重新安装服务
  6. 启动升级后的服务。
  7. 我想避免重启,这样就可以完全编写脚本/自动升级。

    有什么方法可以避免重启吗?也许一个命令行工具会迫使Windows放弃它对旧的.exe的死亡控制?

10 个答案:

答案 0 :(得分:78)

sc delete "service name"

将删除服务。我发现sc utility比挖掘installutil更容易找到。如果您还没有,请记得停止服务。

答案 1 :(得分:14)

使用以下命令,您是否无法在更新前停止服务(并在更新后重新启动)?

net stop <service name>
net start <service name>

每当我测试/部署服务时,只要服务停止,我就可以上传文件而无需重新安装。我不确定你遇到的问题是否有所不同。

答案 2 :(得分:14)

我遇到了和你一样的问题。我有一个系统服务,我想卸载,然后重新安装作为更新的一部分。在某些系统上,如果没有重启,这将无法工作。问题是对DeleteService()的调用会返回ok,但是以下对CreateService()的调用会告诉我服务仍然存在,但标记为删除(错误代码1072)。注册表会反映出这一点,因为子键仍然存在(在HKLM \ System \ CurrentControlSet \ Services下),但“DeleteFlag”设置为1.从那时起,只有重新启动才能解决问题。

有些不起作用的事情:

  • 使用“sc delete”:它有与I相同的问题。调用会返回ok,但服务并没有真正消失,仍然在DeleteFlag = 1的注册表中。
  • 删除注册表中的密钥。服务管理器似乎将数据库保留在内存中,注册表只是下一次启动时的副本。
  • 添加等待循环,等待.exe文件准备好被覆盖,终止进程等。
  • 关闭服务的句柄。哪一个??

但这是有效的:

我在stackoverflow上的一些文章中注意到net.exe也有启动/停止功能(我只知道sc.exe实用程序)。奇怪的是,“net stop svcname”加上“sc delete svcname”工作了!所以net.exe必须做我不做的事。

但net.exe不包含对ControlService()的导入,那么它如何停止服务呢?我发现net.exe会产生net1.exe,但net1.exe也不会导入ControlService()。我使用了很棒的API监视器实用程序(http://www.rohitab.com/apimonitor)来查看net1.exe正在做什么,但它从未调用任何看起来很有希望的东西。

但后来我看到它从NETAPI32.DLL(其名称中至少包含“Service”)导入NetServiceControl()。 MSDN说这个功能已经过时了。不过,我在LMSvc.h中找到了原型,并在此处找到了一些参数说明:http://cyberkinetica.homeunix.net/os2tk45/srvfpgr/369_L2_NetServiceControlorN.html。当您加载NETAPI32.DLL并使用NetServiceControl(NULL, service_name, 3, 0, 0)(3用于SERVICE_CTRL_UNINSTALL,用于停止)后,服务将停止。然后可以删除并重新安装,无需D​​eleteFlag或重新启动!

所以这绝不是删除问题,而是正确停止服务。 NetServiceControl()可以解决问题。对不起,很长的帖子,但我认为它可以帮助有类似问题的人。 (仅供参考,我使用Win7 SP1 x64。)

答案 3 :(得分:3)

如果在.net(我不确定它是否适用于所有Windows服务)

  • 停止服务(这可能是您遇到问题的原因。)
  • InstallUtil -u [可执行文件名称]
  • Installutil -i [可执行文件名称]
  • 再次启动服务......

除非我正在更改服务的公共接口,否则我经常部署我的服务的升级版本,甚至不会无故障地重新安装......我要做的就是停止服务,更换文件并重新启动服务......

答案 4 :(得分:3)

正如StingyJack和mcbala所述,并参考Mike L的评论,我的经验是,在Windows 2000机器上,当卸载/重新安装.Net服务时,“installutil / u”确实即使服务先前已停止,也需要重新启动。另一方面,“sc / delete”不需要重新启动 - 它会立即删除服务(只要它被停止)。

实际上,我经常想知道是否有一个很好的理由“installutil / u”需要重新启动...“sc / delete”实际上是做错了什么/留下了什么东西?

答案 5 :(得分:2)

Jonathan和Charles都是对的...你必须首先停止服务,然后卸载/重新安装。结合他们的两个答案可以得到完美的批处理文件或PowerShell脚本。

我将提到一个谨慎的方法 - Windows 2000 Server(也可能是客户端操作系统)在重新安装之前需要重新启动,无论如何。在重新启动该框之前,必须存在未完全清除的注册表项。 Windows Server 2003,Windows XP和更高版本的OS版本不会遭受这种痛苦。

答案 6 :(得分:2)

  

(所以Windows发布了它   文件)

相反,在服务停止后立即执行Ctrl + Alt + Del并终止服务的.exe。比,您可以在不重新启动的情况下卸载服务。这在过去发生在我身上,它解决了你需要重启的部分。

答案 7 :(得分:2)

是否有必要手动删除服务:

  1. 运行Regedit或regedt32。
  2. 使用以下键找到您服务的注册表项条目:   HKEY_LOCAL_MACHINE / SYSTEM / CurrentControlSet /服务
  3. 删除注册表项
  4. 在服务

    中更新列表之前,您必须重新启动

答案 8 :(得分:0)

我正在使用随.NET Framework打包的InstallUtil.exe。

卸载的用法是:InstallUtil'\ path \ to \ assembly \ with \ the \ installer \ classes'/ u,例如:installutil MyService.HostService.exe /u

/u开关代表卸载,没有它,util执行服务的正常安装。如果服务正在运行,该实用程序将停止服务,并且我从未遇到过Windows保持锁定服务文件的问题。您可以在MSDN上阅读有关InstallUtil的其他选项。

PS:如果你的路径变量中没有installutil,请使用如下所示的完整路径:C:\Windows\Microsoft.NET\Framework\v4.0.30319\InstallUtil.exe "C:\MyServiceFolder\MyService.HostService.exe" /u或者如果你需要64位版本,可以在'C:\ Windows \ Microsoft.NET \ Framework64 \中找到它v4.0.30319 \'。路径中的版本号因.NET版本而异。

答案 9 :(得分:0)

我的批处理文件停止和删除服务

@echo off
title Service Uninstaller
color 0A
set blank=
set service=blank
:start
echo.&echo.&echo.
SET /P service=Enter the name of the service you want to uninstall:  

IF "%service%"=="" (ECHO Nothing is entered
GoTo :start)
cls
echo.&echo.&echo We will delete the service: %service%
ping -n 5 -w 1 127.0.0.1>nul
::net stop %service%
ping -n 2 -w 1 127.0.0.1>nul
sc delete %service%
pause
:end