44

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) ...
Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
Simon
  • 3,235
  • 5
  • 36
  • 47

3 Answers3

86

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.

Community
  • 1
  • 1
Simon
  • 3,235
  • 5
  • 36
  • 47
  • This worked out in VB for me, using a C# to VB converter, and I had to add references to System.Configuration.Install and System.ServiceProcess – user2728841 Apr 13 '21 at 13:15
1

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.

Bakudan
  • 19,134
  • 9
  • 53
  • 73
Mihailo
  • 754
  • 3
  • 6
  • Btw, you have an option, when adding a new item to a project, to select Windows Service (right click on project, in popup menu choose Add -> New Item ... and find Windows Service there). After adding it like that you can set properties of the service nicely and add installers etc. – Mihailo Nov 10 '10 at 15:03
  • You can always look at code behind to see how it's implemented. (The code won't be the prettiest I hear that, but again, it's a start) – Mihailo Nov 11 '10 at 17:47
0

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.

Kiquenet
  • 14,494
  • 35
  • 148
  • 243
Myra
  • 3,646
  • 3
  • 38
  • 47
  • Thank you, that article realy helped me. But in article, author used installutil. I dont want to use installutil. Is there any option? Answer is in this article http://stackoverflow.com/questions/1449994/inno-setup-for-windows-service/1450051#1450051 but I dont know how to use it. – Simon Nov 10 '10 at 13:47
  • Why would you not want to install a service with installutil? If it's because of permissions you won't be able to install a service without admin rights. There's no work around for that. – Jeff LaFay Nov 10 '10 at 14:09
  • Actually, I am still using installutil, but throught ManagedInstallerClass.InstallHelper. That's the point. When I deploy my program, I don't need to deploy installutil.exe also. Installation the WS is made during aplication install with Inno Setup, and this is made under admin rights, so no problem... – Simon Nov 11 '10 at 09:45