Rose debug info
---------------

Windows Service .NET

Наткнулся на отличную статью о том, как создавать Windows Service на .NET, решил перепостить сюда.

Создаём win-сервис проект — в нем есть класс сервиса (отнаследован от ServiceBase). В нем оверрайдим функции OnStart(), OnStop()...

public partial class MyService : ServiceBase

{

    System.Windows.Forms.Timer timerTest;

    Form formTest;

    Thread messageThread;

    protected override void OnStart(string[] args) 

    { 

        //При запуске службы запускаем новый поток 

        messageThread = new Thread(new ThreadStart(ThreadProc)); 

        messageThread.Start(); 

        messageThread.IsBackground = true;

    }

    void ThreadProc()

    {

        //Создаем во вновь созданном потоке форму и таймер 

        formTest = new Form();

        timerTest = new System.Windows.Forms.Timer();

        timerTest.Tick += new EventHandler(timer_Tick);

        timerTest.Interval = 2000;

        timerTest.Start();

        formTest.Show();

        //Запускаем цикл выборки сообщений из очереди сообщений потока 

        Application.Run(formTest); 

    }

    void timer_Tick(object sender, EventArgs e)

    {

        StreamWriter writer = File.AppendText("c:\\1.txt");

        writer.WriteLine(DateTime.Now.ToString());

        writer.Close();

    }

}

Компилится все нормально но при попытке запустить — ругается что не может запустить из под дебагера. ( «Cannot start service from the command line or a debugger....»). Оно и правильно ибо это сервис а просто WinForms приложение — его регистрировать надо.

делается это с помощью InstallUtil.exe:

C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\InstallUtil.exe C:\MyProjects\WindowsService1\WindowsService1\obj\Debug\WindowsService1.exe

Но! просто так оно показывает незамысловатую фигуру из одного пальца и не регистрируется, то есть просто не появляется среди списка сервисов. Тут главное не начать тупить и не копать в сторону прав доступа и прочей херни.

Нужен инсталлер. Добавлем: Add->Installer Class (просто класс наследованный от System.Configuration.Install.Installer) и вот это:

[RunInstaller(true)]

public partial class MyInstaller : Installer

{

    private System.ServiceProcess.ServiceInstaller serviceInstaller1;

    private System.ServiceProcess.ServiceProcessInstaller serviceProcessInstaller1;

    public MyInstaller()

    {

        InitializeComponent();

        this.serviceInstaller1 = new System.ServiceProcess.ServiceInstaller();

        this.serviceProcessInstaller1 = new System.ServiceProcess.ServiceProcessInstaller();

        // 

        // serviceInstaller1

        // 

        this.serviceInstaller1.DisplayName = "MyServiceDisplayName";

        this.serviceInstaller1.ServiceName = "MyServiceServiceName";

        // 

        // serviceProcessInstaller1 

        // 

        this.serviceProcessInstaller1.Account = System.ServiceProcess.ServiceAccount.LocalSystem;

        this.serviceProcessInstaller1.Password = null;

        this.serviceProcessInstaller1.Username = null;

        // 

        // ProjectInstaller

        // 

        this.Installers.AddRange(new System.Configuration.Install.Installer[] {

            this.serviceInstaller1,this.serviceProcessInstaller1});

    }

}

Note: не забываем про [RunInstaller(true)] иначе никто не поймет что это инсталлер.

После этого регистрация проходит нормально и наш сервис с названием MyServiceDisplayName можну увидеть среди [ Панель Управления -> Администрирование -> Службы ] .

Там мы его и запускам и смотрим как сервис начинает гадить в файлик C:\1.txt.

Note: потребуются референсы на System.Configuration.Install, System.ServiceProcess, System.Windows.Forms.

Оригинал на: http://community.livejournal.com/tyaps_asp/20944.html