2012-03-27 331 views
8

我有一项服务。我前一段时间安装了它。我需要对服务进行更新。我去了“添加/删除程序”并查找我的服务,但没有安装。我看着services.msc,它在那里,停下来。我能够开始并停止它。我以管理员身份运行命令提示符并运行sc delete [服务名称],并收到“指定的服务不作为已安装的服务存在”。我在命令提示符下执行了一个sc查询,并且它没有被返回。我右键单击安装程序,单击卸载并收到“此操作仅适用于当前安装的产品。”我也尝试修复,并得到相同的消息。错误1001:指定的服务已存在。无法删除现有服务

我已经重新启动了机器几次,并没有运气得到这项服务卸载。我正在使用随Visual Studio一起安装的基本安装项目模板。我试过改变程序的名字,增加版本号。

如何卸载显然存在的服务,并防止将来发生这种情况?

+1

要清楚,有一个服务名称和一个服务显示名称。有时候人们会忘记services.msc中的“name”列是服务的显示名称。您通过右键单击您的服务并转到属性来获得服务名称。 – Tung 2012-03-27 18:46:53

+0

@Tung我查过了,他们都是一样的。 – 2012-03-27 18:48:51

+1

迁移到http://www.superuser.com?这不是一个真正的编程问题。 – CodingWithSpike 2012-03-27 20:45:19

回答

0

您是否曾尝试在Windows注册表中查找与该服务有关的某些垃圾?

你应该看看这个文件夹:HKEY_LOCAL_MACHINE \系统\ CurrentControlSet \服务\

+0

不幸的是,我没有访问注册表。无论如何,我并不总是感觉舒服,所以我希望有一些事情我可以做,而不必去那里。我要求访问注册表,但有很多繁文associated节与此相关联。 – 2012-03-27 19:08:07

6

如果您有包括服务安装程序使用InstallUtil.exe /u <process.exe> InstallUtil.exe在\Windows\Microsoft.Net\Framework\v4.0.30319

发现在该.exe安装项目,包括在所有的自定义操作为您服务,也卸载

(右键单击该项目,自定义操作)

心连心

马里奥

3

这是完全正常的,服务不列入添加/删除程序,该列表为软件包,而不是服务。 (一个程序包或程序可能包含多项服务,但它通常不会安装任何程序)。

显然,该服务是手动安装的,并非作为产品的一部分,即使这个服务器通常会安装产品你的安装包。

使用sc delete是正确的。您需要在双引号中包含服务的(简称)名称(除非它只是一个单词),但没有别的。

如果不成功,请在您的注册表中访问HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services,分别为32位和64位(分别为regedt32.exeregedit.exe)。你甚至可以直接删除那里的服务,但是显然你应该从可逆的变化开始,以诊断你的服务是如何命名的,以及为什么sc没有看到它的名字,并且只有在其他所有事情都失败并且备份后才使用直接的注册表访问您的注册表(谷歌此程序指定您的操作系统)。

1

今天同样发生在我身上。唯一的解决方案是从Windows添加/删除工具修复安装文件。修复安装文件后,请卸载并重新安装。

3

**如果需要使用仅安装完成,请按:

这可以通过明确的执行现有的服务中移除(卸载),然后让新版本的安装的处理。 对于这一点,我们需要如下更新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; 
     } 
    } 
} 

PS:随着上述变化,也请考虑更新安装版本,产品代码(和optionall的UpgradeCode)为好做法,更好的版本管理,跟踪和维护

+0

这是一个很好的答案,但我发现你可以得到相同的行为,而无需手动编辑ProjectInstaller.Designer.cs(这是一个自动生成的源文件,编辑是危险的,因为VS可以重新生成它,所以你可以结束失去你的改变)。您可以在事件详细信息面板的serviceProcessInstaller属性选项卡中绑定到BeforeInstall事件。 – andreapier 2016-04-28 14:39:20

+0

@andreapier:感谢您的评论。是的,这是非常真实的。这可以通过属性选项卡来实现。在这里,我只是认为理解内部结构会更容易。感谢您的反馈。保持良好的工作。 – ShivanandSK 2016-05-03 03:31:18

0

以防万一任何人都遇到这个问题:

什么对我来说更新我的安装程序的名称,版本和ProductCode。无论如何,一定要遵循良好的版本控制实践。

相关问题