2

I've create a setup project for my windows service. It installs fine, however, if i uninstall the project (either by add / remove programs, or right click the setup project in VS - Uninstall) it does not seem to remove the service.

I have to use sc delete at the command line to do this, and then restart.

Have i set something up wrong?

Alex
  • 37,502
  • 51
  • 204
  • 332
  • Did our advice not offer any help with this? http://stackoverflow.com/questions/1560407/c-windows-service-not-appearing-in-services-list-after-install – Jon Seigel Jan 25 '10 at 17:22
  • @Jon Seigel, looks like a different question to me. In the original he was asking about how to make his service show up in the services panel. Here he's asking how to make it show up in the add/remove programs list (or programs and whatever it's called now). – Samuel Neff Jan 25 '10 at 17:27
  • well, yes - but it doesn't cover uninstalling.... It says for windows 2000 will require restart - but this is windows 7! – Alex Jan 25 '10 at 17:35
  • 1
    @Sam: The instructions include the custom actions required for uninstall. – Jon Seigel Jan 25 '10 at 18:10
  • The instructions linked to by Jon Siegel worked for me. Previously I only had the "Primary output" under the Install Custom Action. Adding the Primary output to Uninstall as well worked so that an Add/Remove Programs removal of the Installer removed the service entirely. – nodmonkey Feb 07 '12 at 12:02

3 Answers3

2

In your Installer class (which you call from your custom actions), make sure you override UnInstall method and call <pathToFramework>\InstallUtil.exe /u <pathToServiceExe> to uninstall the service.

Kev
  • 118,037
  • 53
  • 300
  • 385
0

I'm not sure if there is an easy way to do this within an installer project, but here's how we do it in code. Our service internally does the uninstall when you pass "/uninstall" on the command line.

public static readonly string UNINSTALL_REG_KEY = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
public static readonly string UNINSTALL_REG_GUID = "{1C2301A...YOUR GUID HERE}";

using (RegistryKey parent = Registry.LocalMachine.OpenSubKey(UNINSTALL_REG_KEY, true))
{
    try
    {
        RegistryKey key = null;

        try
        {
            key = parent.OpenSubKey(UNINSTALL_REG_GUID, true);
            if (key == null)
            {
                key = parent.CreateSubKey(UNINSTALL_REG_GUID);
            }

            Assembly asm = typeof (Service).Assembly;
            Version v = asm.GetName().Version;
            string exe = "\"" + asm.CodeBase.Substring(8).Replace("/", "\\\\") + "\"";

            key.SetValue("DisplayName", DISPLAY_NAME);
            key.SetValue("ApplicationVersion", v.ToString());
            key.SetValue("Publisher", "Company Name");
            key.SetValue("DisplayIcon", exe);
            key.SetValue("DisplayVersion", v.ToString(2));
            key.SetValue("URLInfoAbout", "http://www.company.com");
            key.SetValue("Contact", "support@company.com");
            key.SetValue("InstallDate", DateTime.Now.ToString("yyyyMMdd"));
            key.SetValue("UninstallString", exe + " /uninstallprompt");
        }
        finally
        {
            if (key != null)
            {
                key.Close();
            }
        }
    }
    catch (Exception ex)
    {
        throw new Exception(
            "An error occurred writing uninstall information to the registry.  The service is fully installed but can only be uninstalled manually through the command line.",
            ex);
    }
}
Samuel Neff
  • 73,278
  • 17
  • 138
  • 182
0

Take a look at the ServiceInstaller documentation on MDSN. You add a class that inherits from System.Configuration.Install.Installer, create a ServiceInstaller and add that ServiceInstaller to the Installers properties.

Once you do this the installer project should be able to take care of installing and uninstalling for you.

Example of an installer class:

/// <summary>
/// The installer class for the application
/// </summary>
[RunInstaller(true)]
public class MyInstaller : Installer
{
    /// <summary>
    /// Constructor for the installer
    /// </summary>
    public MyInstaller()
    {
        // Create the Service Installer
        ServiceInstaller myInstaller = new ServiceInstaller();
        myInstaller.DisplayName = "My Service";
        myInstaller.ServiceName = "mysvc";

        // Add the installer to the Installers property
        Installers.Add(myInstaller);
    }
}
sirchristian
  • 521
  • 1
  • 6
  • 10