Simon
Simon

Reputation: 3285

Self install Windows Service in .NET

I have read this question. I have same issue, but I don't understand the answer from lubos hasko. How exactly can I do it? Can you someone post me full walkthrough?

When I run code below, something is installed, but in list of service, I could not find it.

I have this, but this not work:

using System;
using System.Collections.Generic;
using System.Configuration.Install;
using System.Linq;
using System.Reflection;
using System.ServiceProcess;
using System.Text;
using System.IO;

namespace ConsoleApplication1
{

public class Service1 : ServiceBase
{
    public Service1()
    {
        File.AppendAllText("sss.txt", "ccccc");
    }

    protected override void OnStart(string[] args)
    {
        File.AppendAllText("sss.txt", "asdfasdf");
    }

    protected override void OnStop()
    {
        File.AppendAllText("sss.txt", "bbbbb");
    }


    static void Main(string[] args)
    {
        if (System.Environment.UserInteractive)
        {
            string parameter = string.Concat(args);
            switch (parameter)
            {
                case "--install":
                    ManagedInstallerClass.InstallHelper(new string[] { Assembly.GetExecutingAssembly().Location });
                    break;
                case "--uninstall":
                    ManagedInstallerClass.InstallHelper(new string[] { "/u", Assembly.GetExecutingAssembly().Location });
                    break;
            }
        }
        else
        {
            ServiceBase.Run(new Service1());
        }


        Console.ReadKey();
    }
 }
}

I dont understad this either:

if (System.Environment.UserInteractive) ...

Upvotes: 46

Views: 53645

Answers (3)

Simon
Simon

Reputation: 3285

This is my complete solution, and it works. It is basically the same answer as in this question.

using System;
using System.Configuration.Install;
using System.Reflection;
using System.ServiceProcess;
using System.IO;

namespace ConsoleApplication1
{
    class Program : ServiceBase
    {
        static void Main(string[] args)
        {

            AppDomain.CurrentDomain.UnhandledException += CurrentDomainUnhandledException;


            if (System.Environment.UserInteractive)
            {
                string parameter = string.Concat(args);
                switch (parameter)
                {
                    case "--install":
                        ManagedInstallerClass.InstallHelper(new string[] { Assembly.GetExecutingAssembly().Location });
                        break;
                    case "--uninstall":
                        ManagedInstallerClass.InstallHelper(new string[] { "/u", Assembly.GetExecutingAssembly().Location });
                        break;
                }
            }
            else
            {
                ServiceBase.Run(new Program());
            }



        }

        private static void CurrentDomainUnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            File.AppendAllText(@"C:\Temp\error.txt", ((Exception)e.ExceptionObject).Message + ((Exception)e.ExceptionObject).InnerException.Message);
        }

        public Program()
        {
            this.ServiceName = "My Service";
            File.AppendAllText(@"C:\Temp\sss.txt", "aaa");

        }

        protected override void OnStart(string[] args)
        {
            base.OnStart(args);

            File.AppendAllText(@"C:\Temp\sss.txt", "bbb");
        }

        protected override void OnStop()
        {
            base.OnStop();

            File.AppendAllText(@"C:\Temp\sss.txt", "ccc");
        }
    }
}

and in same project create this class:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration.Install;
using System.Linq;
using System.ServiceProcess;
using System.Text;

namespace ConsoleApplication1
{
    [RunInstaller(true)]
    public class MyWindowsServiceInstaller : Installer
    {
        public MyWindowsServiceInstaller()
        {
            var processInstaller = new ServiceProcessInstaller();
            var serviceInstaller = new ServiceInstaller();

            //set the privileges
            processInstaller.Account = ServiceAccount.LocalSystem;

            serviceInstaller.DisplayName = "My Service";
            serviceInstaller.StartType = ServiceStartMode.Automatic;

            //must be the same as what was set in Program's constructor
            serviceInstaller.ServiceName = "My Service";
            this.Installers.Add(processInstaller);
            this.Installers.Add(serviceInstaller);
        }
    }
}

Run this program with parameters --install/--uninstall as Administrator on Windows 7. Check the error log in temp. Check working log on the same path.

Upvotes: 88

Myra
Myra

Reputation: 3656

System.Environment.UserInteractive property tells you that whether a Windows process or a service like IIS that runs without a user interface.

If this property is false, do not display modal dialogs or message boxes because there is no graphical user interface for the user to interact with. Source

Check this article as well.

Upvotes: 0

Mihailo
Mihailo

Reputation: 764

First of all, in your Service1 constructor set ServiceName property.

Excerpt from MSDN:

The minimum you need to implement in the constructor for a class inherited from ServiceBase is to set the ServiceName on your component. No other processing is specifically required in the constructor. You should handle most initialization in OnStart rather than in the constructor.

Second of all you need to pass arguments to your service when running it from command line. --install for install, --uninstall for uninstall - look at your switch statement it's doing it on input arguments.

Upvotes: 1

Related Questions