【问题标题】:How to force uninstallation of windows service如何强制卸载windows服务
【发布时间】:2010-09-18 12:35:10
【问题描述】:

我使用 installUtil.exe 安装了 Windows 服务。

更新代码后,我再次使用 installUtil.exe 安装服务,无需先卸载原始版本。

当我现在尝试卸载服务时,installUtil.exe 成功完成卸载,但服务仍然出现。

如果我尝试更改其属性,我会收到消息“服务已标记为删除”。

如何强制删除(最好不重启服务器)?

【问题讨论】:

标签: .net windows-services


【解决方案1】:

过去让我印象深刻的一件事是,如果您正在运行服务查看器,那么这会阻止服务被完全删除,因此请事先关闭它

【讨论】:

  • 我简直不敢相信打开查看器会破坏服务删除 - 多么愚蠢!
  • 这对微软来说太愚蠢了,但它确实有效。由于某些无法解释的原因,打开服务查看器有时会阻止它们被正确删除。
  • 我认为这个答案会有数百个类似的 cmets。我刚刚在这个愚蠢的问题上浪费了 30 分钟...
  • 似乎 SysInternals 进程资源管理器也锁定了服务(可能还有任务管理器),所以请确保你也关闭它们!
  • 还要确保使用 cmd 提示符。 PowerShell 没有显示任何错误,但也没有删除。
【解决方案2】:

您不必重新启动机器。以提升模式启动 cmd 或 PowerShell。

sc.exe queryex <SERVICE_NAME>

然后你会得到一些信息。将显示一个 PID 编号。

taskkill /pid <SERVICE_PID> /f

/f 在哪里强制停止。

现在您可以安装或启动您的服务了。

【讨论】:

  • 在除重新启动之外的所有其他操作都失败的情况下出色地工作 - 非常高兴!
  • 这对我不起作用 - 我的服务的 pid 返回 0,它不允许我删除关键系统进程。
  • A+ 太棒了。使用 sc delete 然后上面的。
  • 没有工作,因为 PID 为 0,这解决了我的问题 - (SC) DeleteService FAILED 1072
  • 绝对有帮助!就我而言,只有重新启动才能奏效。甚至没有删除注册表中的服务目录!不过有个问题:如果您在 PowerShell 中工作,请使用:sc.exe queryex &lt;SERVICENAME&gt;。因为sc 也是Set-Content 的别名,所以当你使用它时它会静默失败。
【解决方案3】:

好吧,如果卸载没有删除任何机会,您可以使用SC.EXE强制删除任何Windows服务。

sc delete <Service_Name>

阅读更多关于“MS Techno 博客”Deleting Services Forcefully from Services MMC

【讨论】:

  • 谢谢。注意,如果“服务名称”与“显示名称”不同,可以在服务的属性中获取“服务名称”。
  • sc delete 也会报告“服务被标记为删除”,如果有一个句柄对服务开放。
  • @GuiSim 谢谢你,我怀疑很多人会像我一样输入显示名称!
  • 试过了,但得到了这个消息:[SC] DeleteService FAILED 1072: The specified service has been marking for delete.
  • 如果服务名称之间有空格,那么我们需要使用双引号提及服务名称。例如:sc 删除“服务名称”
【解决方案4】:

我知道这不会有帮助,但它可能会在未来帮助某人。

我刚刚遇到了同样的问题,关闭并重新打开服务管理器从注册表中删除了两个条目并完成了服务的卸载。

在此之前,刷新服务管理器没有帮助。

【讨论】:

  • 感谢您的参与。我的经历与您描述的完全一样。
【解决方案5】:
sc delete sericeName

在执行此操作之前,请确保服务已停止。我大部分时间都看过这部作品。有时我看到 Windows 卡在某些东西上并且它坚持要重新启动。

【讨论】:

  • 只是一个补充......我必须以管理员身份运行我的 dos 提示符/.NET 提示符才能获得运行 sc delete 命令的访问权限......以防万一其他人遇到这个问题。
  • 在 SC DELETE 之前运行 "NET STOP " 以确保在删除之前停止服务
  • 这也是我的经验,我最终不得不重新启动以删除仅部分卸载的顽固服务(它仍然以代码 2 显示在管理单元中)。重新启动是最终让它消失的原因。
【解决方案6】:

这对我有用

$a = Get-WmiObject Win32_Service | Where-Object {$_.Name -eq 'psexesvc'}
$a.Delete()

【讨论】:

  • 如果您的输出显示ReturnValue : 16,则该命令失败并显示“此服务正在从系统中删除”。来自 Microsoft here 的 ReturnValues 的完整列表
【解决方案7】:

如果打开,请关闭 cmd 和服务窗口,然后通过右键单击并选择以管理员身份运行再次启动 cmd。如果sc delete serviceName 不起作用或任何事情都不起作用。

http://weblogs.asp.net/avnerk/archive/2007/09/05/windows-services-services-msc-and-the-quot-this-service-is-marked-for-deletion-quot-error.aspx

【讨论】:

    【解决方案8】:

    很遗憾,您需要重新启动服务器。 那应该删除“已删除”的服务。

    【讨论】:

    • 没有。你不需要重启。查看我的解决方案:)
    • 我实际上更喜欢 user186749 的解决方案。干净整洁。
    【解决方案9】:

    万一这个答案对某人有帮助:如发现 here,您可能会为自己以管理员身份运行 Sysinternals Autoruns 省去很多麻烦。 只需转到“服务”标签并删除您的服务。

    它在我没有任何权限编辑注册表的机器上为我解决了问题。

    【讨论】:

      【解决方案10】:

      您可以手动删除服务的注册表项,位于HKLM\SYSTEM\CurrentControlSet\Services,之后您将不会在服务控制管理器中看到该服务(需要刷新或重新打开才能看到更改),您可以重新安装照常服务。

      【讨论】:

      • 在 Windows 2012 R2 上,导致服务 MMC 管理单元 (Services.MSC) 显示“无法读取说明。错误代码:2”。尽管确保所有其他 MMC 都已关闭并且没有其他用户登录。
      • 我明白了,仅在 Windows 8 和 Windows 10 中测试过(并且有效)。
      • 终于解决了我的问题。我忘记在项目中添加服务安装程序,安装后无法删除我的服务。我建议先导出服务注册树,然后再删除其中的任何内容。非常感谢!
      【解决方案11】:

      另外值得注意的是:

      sc delete "ServiceName"
      

      在 PowerShell 中不起作用,sc 是 PowerShell 中 cmdlet Set-Content 的别名。你需要做的:

      sc.exe delete "ServiceName"
      

      【讨论】:

      • 你救了我。我在 powershell 上做 sc delete
      【解决方案12】:

      这对我有用:

      net stop "MyWindowsService"
      taskkill /F /IM mmc.exe
      sc delete "MyWindowsService"
      

      【讨论】:

        【解决方案13】:

        以下将在不重新启动机器的情况下工作:

        1. 在注册表\HKEY_LOCAL_MACHINE 中搜索(键和值)
        2. 将“旧版”值设置为 0

        【讨论】:

          【解决方案14】:

          您是否尝试在调用卸载之前停止服务?我随机遇到了这个问题。有时我可以在不重新启动的情况下将其删除。我的猜测是它与仍在运行的服务有关

          【讨论】:

            【解决方案15】:

            我来晚了,但想添加一个替代方案,可能看起来很奇怪,但我没有看到其他方式:

            当我每晚在 CI 进程中安装我的 Windows 服务时,我需要一些可以一直工作并且完全自动化的东西。出于某种原因,这些服务在卸载后总是被标记为删除很长时间(5 分钟或更长时间)。因此,我扩展了重装批处理脚本,以确保服务真的被删除(简化版):

            REM Stop the service first
            net stop My-Socket-Server
            
            REM Same as installutil.exe, just implemented in the service
            My.Socket.Server.exe /u
            
            :loop1
                REM Easy way to wait for 5 seconds
                ping 192.0.2.2 -n 1 -w 5000 > nul
                sc delete My-Socket-Server
                echo %date% %time%: Trying to delete service.
                if errorlevel 1072 goto :loop1
            
            REM Just for output purposes, typically I get that the service does not exist
            sc query My-Socket-Server
            
            REM Installing the new service, same as installutil.exe but in code
            My.Socket.Server.exe /i
            
            REM Start the new service
            net start My-Socket-Server
            

            我可以看到,该服务被标记为删除大约 5 分钟(!),直到它最终通过。最后,我不再需要任何手动干预。我将来会扩展脚本,以便在特定时间后发生某些事情(例如 30 分钟后通知)。

            【讨论】:

              【解决方案16】:

              如果您无法在服务中停止该服务,您可以在任务管理器中停止您的windows服务exe。之后,您可以删除该服务。

              【讨论】:

                【解决方案17】:

                刷新服务列表总是对我有用。如果服务窗口是打开的,它会保存一些由于某种原因而存在的内存。 F5,我又重新安装了!

                【讨论】:

                  【解决方案18】:

                  还要确保没有任何可执行文件的实例仍然处于活动状态(无论出于何种原因,该实例可能一直在运行,与服务无关)。

                  我正在打开和关闭 MMC 并寻找要杀死的 PID - 但是在进程资源管理器中查看时,有几个现存的进程正在从一个被遗忘的预定批处理中运行。杀了他们。任务完成。

                  【讨论】:

                    【解决方案19】:

                    有很多关于该主题的论坛问题。

                    我在 windows api 中找到了答案。卸载服务后无需重启电脑。您必须致电:

                    BOOL WINAPI CloseServiceHandle(
                      SC_HANDLE hSCObject
                    );
                    

                    关闭服务的句柄。在 Windows 7 上,它解决了我的问题。 我愿意:

                    • 停止服务
                    • 关闭句柄
                    • 卸载服务
                    • 等待 3 秒
                    • 复制新的exe到目录
                    • 安装服务
                    • 启动服务
                    • 关闭句柄

                    【讨论】:

                    • 如果您不在具有打开句柄的程序中,您在哪里关闭句柄?
                    【解决方案20】:

                    当 TopShelf 出现问题或服务因其他原因失败时,我使用以下几个地方拼凑而成的 PowerShell 用于我们的 Octopus Deploy 实例。

                    $ServiceName = 'MyNaughtyService'
                    $ServiceName | Stop-Service -ErrorAction SilentlyContinue
                    # We tried nicely, now KILL!!!
                    $ServiceNamePID = Get-Service | Where { $_.Name -eq $ServiceName} # If it was hung($_.Status -eq 'StopPending' -or $_.Status -eq 'Stopping') -and
                    $ServicePID = (Get-WmiObject Win32_Service | Where {$_.Name -eq $ServiceNamePID.Name}).ProcessID
                    Stop-Process $ServicePID -Force
                    

                    【讨论】:

                      猜你喜欢
                      • 2018-02-01
                      • 2011-10-25
                      • 1970-01-01
                      • 1970-01-01
                      • 2011-08-06
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 2011-12-10
                      相关资源
                      最近更新 更多