views:

1006

answers:

6

Does anyone know if there is a way to install a Windows service created in C# without making an installer?

+4  A: 

You can use installutil.

From the command line:

installutil YourWinService.exe

This utility is installed with the .NET Framework

Philippe Leybaert
I believe you still need to create an installer in your project for installutil to work with a service's configuration properties:http://www.developer.com/net/net/article.php/11087_2173801_2
Dan Diplo
Dan is correct, you still need to create an installer. The sc command (see below) will allow you to install/delete/start/stop, etc a Windows service without requiring an installer (which seems, to me anyway, the core of the question).This is handy because much of the service metadata (startup type, account name, restart properties, etc) which is baked into the installer can be stored externally. This is doubly useful when combined with scripts for deployment, say MSBuild or Nant, because it doesn't require a recompile.It also means that you can install whether its written in C#, C, C++.
Zach Bonham
You need an 'Installer' Class, but not an installer in the sense of a setup.exe
Nathan Reed
+2  A: 

Hello,

take a look at the InstallUtil tool from M$. http://msdn.microsoft.com/de-de/library/50614e95(VS.80).aspx

Cheers, Tomas

Thomasek
+4  A: 

You could try the windows sc command
C:\WINDOWS\system32>sc create
DESCRIPTION:
SC is a command line program used for communicating with the NT Service Controller and services.

SwDevMan81
+2  A: 

I include a class that does the installation for me. I call the application using command line parameters to install or uninstall the app. I have also in the past included a prompt to the user whether they wanted the service installed when started directly from the command line.

Here's the class I use:

using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using Microsoft.Win32;

namespace [your namespace here]
{
    class IntegratedServiceInstaller
    {
     public void Install(String ServiceName, String DisplayName, String Description,
      System.ServiceProcess.ServiceAccount Account, 
      System.ServiceProcess.ServiceStartMode StartMode)
     {
      System.ServiceProcess.ServiceProcessInstaller ProcessInstaller = new System.ServiceProcess.ServiceProcessInstaller();
      ProcessInstaller.Account = Account;

      System.ServiceProcess.ServiceInstaller SINST = new System.ServiceProcess.ServiceInstaller();

            System.Configuration.Install.InstallContext Context = new System.Configuration.Install.InstallContext();
      string processPath = Process.GetCurrentProcess().MainModule.FileName;
      if (processPath != null && processPath.Length > 0)
      {
                System.IO.FileInfo fi = new System.IO.FileInfo(processPath);
                //Context = new System.Configuration.Install.InstallContext();
                //Context.Parameters.Add("assemblyPath", fi.FullName);
                //Context.Parameters.Add("startParameters", "Test");

                String path = String.Format("/assemblypath={0}", fi.FullName);
                String[] cmdline = { path };
                Context = new System.Configuration.Install.InstallContext("", cmdline);
      }

      SINST.Context = Context;
                SINST.DisplayName = DisplayName;
                SINST.Description = Description;
                SINST.ServiceName = ServiceName;
      SINST.StartType = StartMode;
      SINST.Parent = ProcessInstaller;

            // http://bytes.com/forum/thread527221.html
//            SINST.ServicesDependedOn = new String[] {};

      System.Collections.Specialized.ListDictionary state = new System.Collections.Specialized.ListDictionary();
      SINST.Install(state);

            // http://www.dotnet247.com/247reference/msgs/43/219565.aspx
            using (RegistryKey oKey = Registry.LocalMachine.OpenSubKey(String.Format(@"SYSTEM\CurrentControlSet\Services\{0}", SINST.ServiceName), true))
            {
                try
                {
                    Object sValue = oKey.GetValue("ImagePath");
                    oKey.SetValue("ImagePath", sValue);
                }
                catch (Exception Ex)
                {
//                    System.Console.WriteLine(Ex.Message);
                }
            }

     }
     public void Uninstall(String ServiceName)
     {
      System.ServiceProcess.ServiceInstaller SINST = new System.ServiceProcess.ServiceInstaller();

      System.Configuration.Install.InstallContext Context = new System.Configuration.Install.InstallContext("c:\\install.log", null);
      SINST.Context = Context;
                SINST.ServiceName = ServiceName;
            SINST.Uninstall(null);
     }
    }
}

And here's how I call it:

const string serviceName = "service_name";
const string serviceTitle = "Service Title For Services Control Panel Applet";
const string serviceDescription = "A longer description of what the service does.  This is used by the services control panel applet";
// Install
IntegratedServiceInstaller Inst = new IntegratedServiceInstaller();
Inst.Install(serviceName, serviceTitle, serviceDescription,
    // System.ServiceProcess.ServiceAccount.LocalService,      // this is more secure, but only available in XP and above and WS-2003 and above
    System.ServiceProcess.ServiceAccount.LocalSystem,       // this is required for WS-2000
    System.ServiceProcess.ServiceStartMode.Automatic);
// Uninstall
IntegratedServiceInstaller Inst = new IntegratedServiceInstaller();
Inst.Uninstall(serviceName);
Brad Bruce
A: 

I found A Windows Service without a template to be helpful when I was trying to do the same thng.

mikej
A: 

That was a great help! Thanks!!!

Markus