如何在不重新启动的情况下卸载 Windows 服务并删除其文件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/299604/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to uninstall a windows service and delete its files without rebooting
提问by Nate Sauber
My current project involves deploying an upgraded .exe file that runs as a Windows Service. In order to overwrite the existing .exe with the new version, I currently need to:
我当前的项目涉及部署作为 Windows 服务运行的升级后的 .exe 文件。为了用新版本覆盖现有的 .exe,我目前需要:
- Stop the service
- Uninstall the service
- Reboot the system (so Windows releases it's hold on the file)
- Deploy the new .exe
- Reinstall the service
- Start the upgraded service.
- 停止服务
- 卸载服务
- 重新启动系统(因此 Windows 释放它对文件的保留)
- 部署新的 .exe
- 重新安装服务
- 启动升级后的服务。
I'd like to avoid the reboot, so that this can be a fully scripted/automated upgrade.
我想避免重新启动,以便这可以是完全脚本化/自动化的升级。
Is there any way to avoid rebooting? Maybe a command-line tool that will force Windows to give up it's death grip on the old .exe?
有什么办法可以避免重启?也许一个命令行工具会迫使 Windows 放弃对旧的 .exe 的控制?
回答by StingyHyman
sc delete "service name"
will delete a service. I find that the sc utilityis much easier to locate than digging around for installutil. Remember to stop the service if you have not already.
将删除服务。我发现sc 实用程序比寻找 installutil 更容易找到。如果您还没有停止该服务,请记住停止该服务。
回答by Jonathan S.
Are you not able to stop the service before the update (and restart after the update) using the commands below?
您是否无法使用以下命令在更新前停止服务(并在更新后重新启动)?
net stop <service name>
net start <service name>
Whenever I'm testing/deploying a service I'm able to upload files without reinstalling as long as the service is stopped. I'm not sure if the issue you are having is different.
每当我测试/部署服务时,只要服务停止,我就可以上传文件而无需重新安装。我不确定您遇到的问题是否有所不同。
回答by cxxl
I had sort of the same problem as you. I have a system service that i want to uninstall and afterwards reinstall as part of an update. On certain systems this would not work without a reboot. The problem was that a call to DeleteService() would return ok, but the following call to CreateService() would tell me the service was still there, but marked for deletion (error code 1072). The registry would reflect that, since the subkey was still there (under HKLM\System\CurrentControlSet\Services), but "DeleteFlag" was set to 1. From that point on, only a reboot could fix the situation.
我遇到了和你一样的问题。我有一个系统服务,我想卸载它,然后作为更新的一部分重新安装。在某些系统上,如果不重新启动,这将无法工作。问题是对 DeleteService() 的调用会返回 ok,但对 CreateService() 的以下调用会告诉我该服务仍然存在,但已标记为删除(错误代码 1072)。注册表会反映这一点,因为子项仍然存在(在 HKLM\System\CurrentControlSet\Services 下),但“DeleteFlag”设置为 1。从那时起,只有重新启动才能解决这种情况。
Some things that don't work:
一些不起作用的事情:
- Using "sc delete": it had the same problems as I. The call would return ok, but the service was not really gone and still in the registry with DeleteFlag = 1.
- Deleting the key in the registry. The Service Manager seems to keep a database in memory and the registry is just a copy of it for the next boot.
- Adding wait loops, waiting for .exe files to be ready to be overwritten, killing the process, etc.
- Closing handles to the service. Which ones??
- 使用“sc delete”:它和我有同样的问题。调用会返回ok,但服务并没有真正消失并且仍然在注册表中,DeleteFlag = 1。
- 删除注册表中的键。服务管理器似乎在内存中保存了一个数据库,而注册表只是它下次启动时的副本。
- 添加等待循环、等待 .exe 文件准备好被覆盖、终止进程等。
- 关闭服务的句柄。哪个??
But here is what worked:
但这是有效的:
I noticed in some articles here on stackoverflow that net.exe has start/stop features as well (I only knew of sc.exe utility). And strangely enough, a "net stop svcname" plus a "sc delete svcname" worked! So net.exe must do something I don't do.
我在 stackoverflow 上的一些文章中注意到 net.exe 也具有启动/停止功能(我只知道 sc.exe 实用程序)。奇怪的是,“net stop svcname”加上“sc delete svcname”起作用了!所以 net.exe 必须做一些我不做的事情。
But net.exe doesn't contain an import to ControlService(), so how does it stop the service? I found out that net.exe spawns net1.exe, but net1.exe doesn't import ControlService() as well. I used the great API Monitor utility ( http://www.rohitab.com/apimonitor) to see what net1.exe is doing, but it never called anything that looked promising.
但是 net.exe 不包含对 ControlService() 的导入,那么它是如何停止服务的呢?我发现 net.exe 会生成 net1.exe,但 net1.exe 也不会导入 ControlService()。我使用了很棒的 API Monitor 实用程序 ( http://www.rohitab.com/apimonitor) 来查看 net1.exe 正在做什么,但它从未调用过任何看起来有希望的东西。
But then I saw that it imports NetServiceControl() from NETAPI32.DLL (that had at least "Service" in its name!). MSDN says that this function is obsolete. Nevertheless, I found the prototype in LMSvc.h and some parameter description here: http://cyberkinetica.homeunix.net/os2tk45/srvfpgr/369_L2_NetServiceControlorN.html. When you load NETAPI32.DLL and use NetServiceControl(NULL, service_name, 3, 0, 0)
(3 is for SERVICE_CTRL_UNINSTALL, which is used to stop) the service is stopped afterwards. And it can be deleted and reinstalled afterwards without DeleteFlag or reboot!
但后来我看到它从 NETAPI32.DLL 导入 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,用于停止)后,服务将停止。并且它可以在没有DeleteFlag或重启的情况下被删除和重新安装!
So it was never a problem of deleting, but of stopping the service properly. And NetServiceControl() does the trick. Sorry for the long post, but I thought it might help someone with similar problems. (Just for reference, I use Win7 SP1 x64.)
因此,删除从来都不是问题,而是正确停止服务的问题。而 NetServiceControl() 可以解决问题。很抱歉这篇很长的帖子,但我认为它可能会帮助有类似问题的人。(仅供参考,我使用的是 Win7 SP1 x64。)
回答by Tao
As noted by StingyHyman and mcbala, and in reference to comments made by Mike L, my experience is that on a Windows 2000 machine, when uninstalling / reinstalling .Net services, "installutil /u" doesrequire a reboot, even when the service was previously stopped. "sc /delete", on the other hand, does not require a reboot - it deletes the service right away (as long as it is stopped).
正如 StingyHyman 和 mcbala 所指出的,并参考 Mike L 的评论,我的经验是,在 Windows 2000 机器上,卸载/重新安装 .Net 服务时,“installutil /u”确实需要重新启动,即使服务已关闭以前停止。另一方面,“sc /delete”不需要重新启动 - 它会立即删除服务(只要它停止)。
I have often wondered, actually, whether there is a good reason "installutil /u" requires a reboot... Is "sc /delete" actually doing something wrong / leaving something hanging?
实际上,我经常想知道,是否有充分的理由“installutil /u”需要重新启动……“sc /delete”实际上是在做错什么/让某些东西挂起吗?
回答by Charles Bretana
If in .net ( I'm not sure if it works for all windows services)
如果在 .net 中(我不确定它是否适用于所有 Windows 服务)
- Stop the service (THis may be why you're having a problem.)
- InstallUtil -u [name of executable]
- Installutil -i [name of executable]
- Start the service again...
- 停止服务(这可能是您遇到问题的原因。)
- InstallUtil -u [可执行文件的名称]
- Installutil -i [可执行文件的名称]
- 再次启动服务...
Unless I'm changing the service's public interface, I often deploy upgraded versions of my services without even unistalling/reinstalling... ALl I do is stop the service, replace the files and restart the service again...
除非我要更改服务的公共接口,否则我经常部署服务的升级版本,甚至无需卸载/重新安装......我所做的就是停止服务,替换文件并再次重新启动服务......
回答by Mike L
Both Jonathan and Charles are right... you've got to stop the service first, then uninstall/reinstall. Combining their two answers makes the perfect batch file or PowerShell script.
乔纳森和查尔斯都是对的……你必须先停止服务,然后卸载/重新安装。结合他们的两个答案可以制作完美的批处理文件或 PowerShell 脚本。
I will make mention of a caution learned the hard way -- Windows 2000 Server (possibly the client OS as well) will require a reboot before the reinstall no matter what. There must be a registry key that is not fully cleared until the box is rebooted. Windows Server 2003, Windows XP and later OS versions do not suffer that pain.
我将提到一个艰难的教训——Windows 2000 Server(也可能是客户端操作系统)无论如何都需要在重新安装之前重新启动。必须有一个注册表项在重新启动该框之前未完全清除。Windows Server 2003、Windows XP 和更高版本的操作系统不会遭受这种痛苦。
回答by Patrick Desjardins
(so Windows releases it's hold on the file)
(因此 Windows 释放它对文件的保留)
Instead, do Ctrl+Alt+Del right after the Stop of the service and kill the .exe of the service. Than, you can uninstall the service without rebooting. This happened to me in the past and it solves the part that you need to reboot.
相反,在停止服务后立即执行 Ctrl+Alt+Del 并杀死服务的 .exe。然后,您无需重新启动即可卸载该服务。过去发生在我身上,它解决了您需要重新启动的部分。
回答by chrishawn
Should it be necessary to manually remove a service:
如果需要手动删除服务:
- Run Regedit or regedt32.
- Find the registry key entry for your service under the following key: HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services
- Delete the Registry Key
- 运行 Regedit 或 Regedt32。
- 在以下项下找到您的服务的注册表项:HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services
- 删除注册表项
You will have to reboot before the list gets updated in services
您必须在服务中更新列表之前重新启动
回答by MSkuta
I am using the InstallUtil.exe packed with .NET Framework.
我正在使用 .NET Framework 打包的 InstallUtil.exe。
The usage to uninstall is: InstallUtil '\path\to\assembly\with\the\installer\classes' /u so for example: installutil MyService.HostService.exe /u
卸载的用法是: InstallUtil '\path\to\assembly\with\the\installer\classes' /u 例如: installutil MyService.HostService.exe /u
The /u
switch stands for uninstall, without it the util performs normal installation of the service. The utility stops the service if it is running and I never had problems with Windows keeping lock on the service files. You can read about other options of InstallUtil on MSDN.
所述/u
开关手段卸载,如果没有它,UTIL执行业务的正常安装。如果服务正在运行,该实用程序会停止该服务,而且我从未遇到过 Windows 锁定服务文件的问题。您可以在MSDN上阅读 InstallUtil 的其他选项。
P.S.:if you don't have installutil in your path variable use full path like this: C:\Windows\Microsoft.NET\Framework\v4.0.30319\InstallUtil.exe "C:\MyServiceFolder\MyService.HostService.exe" /u
or if you need 64bit version it can be found in 'C:\Windows\Microsoft.NET\Framework64\v4.0.30319\' .The version number in path varies depending on .NET version.
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 版本而异。
回答by Chris Robertson
My batch file to stop and delete service
我的批处理文件停止和删除服务
@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