51

How do I install a Windows Service programmatically without using installutil.exe?

Stephen Kennedy
  • 20,585
  • 22
  • 95
  • 108
Josh
  • 13,530
  • 29
  • 114
  • 159

5 Answers5

74

You can install the service by adding this code (in the program file, Program.cs) to install itself when run from the commandline using specified parameters:

/// <summary>
        /// The main entry point for the application.
        /// </summary>
        static void Main(string[] args)
        {
            if (System.Environment.UserInteractive)
            {

                if (args.Length > 0)
                {
                    switch (args[0])
                    {
                        case "-install":
                            {
                                ManagedInstallerClass.InstallHelper(new string[] { Assembly.GetExecutingAssembly().Location });
                                break;
                            }
                        case "-uninstall":
                            {
                                ManagedInstallerClass.InstallHelper(new string[] { "/u", Assembly.GetExecutingAssembly().Location });
                                break;
                            }
                    }
                }
            }
            else
            {
                ServiceBase[] ServicesToRun;
                ServicesToRun = new ServiceBase[] { new MyService() };
                ServiceBase.Run(ServicesToRun);
            }
        }
Mark Redman
  • 24,079
  • 20
  • 92
  • 147
  • 6
    Although this is a clear and suitable way to do that instead of using "low level" advapi32.dll, the framework documentation says "This API supports the .NET Framework infrastructure and is not intended to be used directly from your code.". But I still prefer "ManagedInstallerClass" and the risks of future incompatibilities in new .net versions. (http://msdn.microsoft.com/pt-br/library/system.configuration.install.managedinstallerclass) – Luciano Aug 08 '12 at 18:06
  • I wonder, if I call `ManagedInstallerClass.InstallHelper(srvExe)` from another console app, would this app wait till `InstallHelper` exits (with installation finnished)? Thanks. – Andrey K. Aug 14 '18 at 12:53
  • Could be new in recent framework versions (4.8), but the System.Configuration.Install namespace, and hence the ManagedInstaller class, exists only in debug builds. – Luc VdV Jun 02 '22 at 07:19
  • Correction to my previous comment: for debug builds you can include a reference to System.Configuration.Install.dll, for release builds System.Configuration.dll must also be added. – Luc VdV Jun 02 '22 at 07:25
11

I use the method from the following CodeProject article, and it works great.

Windows Services Can Install Themselves

TWA
  • 12,756
  • 13
  • 56
  • 92
  • 3
    Great link; however, it references a link written by Mahmoud Nasr that is broken. I used this and it works for me. https://msdn.microsoft.com/en-us/library/zt39148a(v=vs.110).aspx?cs-save-lang=1&cs-lang=csharp#code-snippet-1 – D. Kermott Jan 18 '17 at 21:41
  • I wonder, if I call `ManagedInstallerClass.InstallHelper(srvExe)` from another console app, would this app wait till `InstallHelper` exits (with installation finnished)? Thanks. – Andrey K. Aug 14 '18 at 12:53
5

I install and uninstall my Windows Service via the command line, e.g., MyWindowsService.exe -install and MyWindowsService.exe -uninstall, to avoid using installutil.exe myself. I've written a set of instructions for how to do this here.

Community
  • 1
  • 1
Matt Davis
  • 45,297
  • 16
  • 93
  • 124
0

I cannot comment bc of missing reputation, but regarding Mark Redman's Solution - If you wonder you cannot find your key in the given path, checkout the WOW6432Node

From AdvancedInstaller:

"The Wow6432Node registry entry indicates that you are running a 64-bit Windows version.

The operating system uses this key to display a separate view of HKEY_LOCAL_MACHINE\SOFTWARE for 32-bit applications that run on 64-bit Windows versions. When a 32-bit application writes or reads a value under the HKEY_LOCAL_MACHINE\SOFTWARE\<company>\<product> subkey, the application reads from the HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\<company>\<product> subkey.

A registry reflector copies certain values between the 32-bit and 64-bit registry views (mainly for COM registration) and resolves any conflicts using a "last-writer-wins" approach."

Taki7o7
  • 197
  • 2
  • 11
0

None of the above work with .Net Core, however see my answer here on a possible solution: https://stackoverflow.com/a/76732404/440503 using System.Diagnostics.Process to start sc.exe.

Use sc.exe from a command line with no arguments to find its usage.

AndyB
  • 101
  • 4