错误1001:指定的服务已经存在。无法删除现有服务。

13

我有一个服务。我在一段时间前安装了它。现在需要对该服务进行更新。我去了“添加/删除程序”并查找我的服务,但是没有找到它的安装位置。我查看了services.msc,发现它停止了。我可以启动和停止它。我以管理员身份运行命令提示符,并运行sc delete [Service Name]命令,结果显示“指定的服务不存在于已安装的服务中”。我在命令提示符中执行了sc query命令,但未返回该服务。我右键单击安装程序,选择卸载,结果收到“此操作仅适用于当前已安装的产品”的提示。我也尝试了修复,但收到了相同的消息。

我已经重新启动机器几次,但无法卸载此服务。我使用Visual Studio安装的基本设置项目模板。我尝试更改程序名称并增加版本号。

如何卸载已存在的服务,并防止今后出现类似情况?


1
只是为了明确起见,有一个服务名称和一个服务显示名称。有时人们会忘记在services.msc中的“名称”列是服务的显示名称。您可以通过右键单击服务并转到属性来获取服务名称。 - Tung
@Tung 我已经核实了,它们是一样的。 - Larry Gasik
1
迁移到http://www.superuser.com吗? 这不是一个真正的编程问题。 - CodingWithSpike
6个回答

10

如果需要仅使用设置完成此操作,请按照以下步骤进行:

可以通过显式实现现有服务的移除(卸载),然后允许安装较新版本来处理此问题。 为此,我们需要更新ProjectInstaller.Designer.cs如下:

请在InitializeComponent()函数开头处添加以下代码行,以在当前安装程序尝试重新安装服务之前触发卸载现有服务的事件。在这里,如果服务已经存在,我们将卸载该服务。

添加以下命名空间:

using System.Collections.Generic;
using System.ServiceProcess;

按照之前描述的方式添加以下代码行:

this.BeforeInstall += new
System.Configuration.Install.InstallEventHandler(ProjectInstaller_BeforeInstall);

例子:

private void InitializeComponent()
{
    this.BeforeInstall += new System.Configuration.Install.InstallEventHandler(ProjectInstaller_BeforeInstall);

    this.serviceProcessInstaller1 = new System.ServiceProcess.ServiceProcessInstaller();
    this.serviceInstaller1 = new System.ServiceProcess.ServiceInstaller();
    // 
    // serviceProcessInstaller1
    // 
    this.serviceProcessInstaller1.Account = System.ServiceProcess.ServiceAccount.LocalSystem;
    this.serviceProcessInstaller1.Password = null;
    this.serviceProcessInstaller1.Username = null;
    // 
    // serviceInstaller1
    // 
    this.serviceInstaller1.Description = "This is my service name description";
    this.serviceInstaller1.ServiceName = "MyServiceName";
    this.serviceInstaller1.StartType = System.ServiceProcess.ServiceStartMode.Automatic;
    // 
    // ProjectInstaller
    // 
    this.Installers.AddRange(new System.Configuration.Install.Installer[]{
            this.serviceProcessInstaller1,
            this.serviceInstaller1
        }
    );
}
下面的代码将被事件调用,如果服务存在,则卸载该服务。
void ProjectInstaller_BeforeInstall(object sender, System.Configuration.Install.InstallEventArgs e)
{
    List<ServiceController> services = new List<ServiceController>(ServiceController.GetServices());

    foreach (ServiceController s in services)
    {
        if (s.ServiceName == this.serviceInstaller1.ServiceName)
        {
            ServiceInstaller ServiceInstallerObj = new ServiceInstaller();
            ServiceInstallerObj.Context = new System.Configuration.Install.InstallContext();
            ServiceInstallerObj.Context = Context;
            ServiceInstallerObj.ServiceName = "MyServiceName";
            ServiceInstallerObj.Uninstall(null);

            break;
        }
    }
}

顺便提一下,除了以上更改,请考虑更新设置版本、产品代码(以及可选的升级代码),以便进行良好的实践、更好的版本管理、跟踪和维护。


1
这是一个很好的答案,但我发现你可以在不手动编辑ProjectInstaller.Designer.cs的情况下获得相同的行为(这是一个自动生成的源文件,编辑它是危险的,因为VS可能会重新生成它,所以您可能会失去更改)。您可以在serviceProcessInstaller的属性选项卡中绑定到BeforeInstall事件,在事件详细信息面板中。 - andreapier
@andreapier:感谢您的评论。是的,那是非常正确的。这可以通过属性选项卡实现。在这里,我只是认为这样更容易理解内部情况。感谢您的反馈。继续保持良好的工作。 - ShivanandSK
请注意,如果您这样做,它将应用于您的设置exe,当您尝试安装新的设置exe时,卸载代码将从设置exe运行(据我所知),因此您可能需要手动删除现有的安装并重新安装以使此代码起作用! - NibblyPig

9
如果您有包含服务安装程序的 .exe 文件,请使用 InstallUtil.exe /u <process.exe> 进行安装。 InstallUtil.exe 位于 \Windows\Microsoft.Net\Framework\v4.0.30319
在设置项目中,将您的服务包括在所有自定义操作中,还包括卸载操作(右键单击项目,选择 Custom Action)。
希望这能帮到您。
Mario

5
服务未在"添加/删除程序"列表中显示是完全正常的,该列表仅适用于软件包,不适用于服务。(一个软件包或程序可能包含多个服务,但通常不会安装任何内容。)
显然,该服务是手动安装的,而不是作为产品的一部分安装的,即使这个特定的服务通常会随产品的安装包一起安装。
使用"sc delete"命令是正确的。您需要在双引号(除非它只是一个单词)中包括服务的(简)短名称,但没有其他内容。
如果失败,请在注册表中访问"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services"的32位和64位版本(regedt32.exe和regedit.exe)。您甚至可以直接删除那里的服务,但您应该首先进行可逆转的更改来诊断您的服务的确切名称以及为什么"sc"无法看到其名称,并且在所有其他方法失败并且在备份注册表后才使用直接注册表访问(使用Google搜索此过程并指定您的操作系统)。

1
今天我也遇到了同样的问题。唯一的解决方案是从Windows添加/删除工具中修复安装文件。修复安装文件后,卸载并重新安装即可。

0

你尝试在Windows注册表中查找与该服务相关的垃圾吗?

你应该查看这个文件夹:HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ Services \


不幸的是,我没有访问注册表的权限。即使有权限,我也不总是感到舒服进入那里,所以我希望有一些方法可以避免进入那里。我已经请求访问注册表,但是与此相关的手续非常繁琐。 - Larry Gasik
我试图删除与我的服务相关联的文件夹,但服务仍然显示出来,然后我不得不重新启动计算机。 - M. Fawad Surosh
当处理安装程序时,手动编辑注册表并不起帮助作用。 - Emiswelt

0

以防其他人遇到此问题:

对我有用的是更新安装程序的名称、版本和产品代码。无论如何,应该遵循良好的版本控制实践。


1
这与服务完全无关。 - Emiswelt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接