Pull to refresh

Создание на C# службы Windows в Visual Studio 2015

Хочу описать процесс создание и тестирования службы Windows на C#. В качестве среды разработки буду использовать Visual Studio 2015. В качестве примера создам службу, которая пишет в файл данные о событиях. Исходный код проекта доступен на GitHub.

Для создания службы я создаю решение с тремя проектами:

Приложение Windows Forms


Создание новой службы начинается, с создания windows приложения (шаблон проекта «Приложение Windows Forms»). Оно нам понадобится для тестирования службы. Приложение будет состоять из одной формы:



Разработка логики


На втором этапе создается проект «Библиотека классов». Именно здесь создаются классы описывающие логику работы будущей службы. Выделение логики в библиотеку классов позволяют нам пока не думать о реализации службы, а вести разработка стандартной windows программы. Плюсом такого подхода является: простота тестирования, легкость повторного использования кода, возможность создания автоматических тестов. В данном примере в библиотеке классов мы создадим только один класс:

    public class LogFile : System.IDisposable
    {
        StreamWriter file;

        public string FileName { get; private set; }

        public LogFile()
        {
            CreateFile();
        }

        ~LogFile()
        {
            Dispose();
        }

        public void Dispose()
        {
            if (file != null)
            {
                file.Close();
            }
        }

        private void CreateFile()
        {
            FileName = Path.GetTempFileName();
            file = File.CreateText(FileName);
        }

        public void Write(string text)
        {
            file.WriteLine(text);
        }
    }

Для тестирования — используем приложение созданное на первом этапе.

Создание службы


Когда логика новой службы написана и оттестирована, приступаем к созданию службы. В качестве шаблона используем стандартный шаблон: «Служба Windows». Реализация службы должна выглядеть примерно так:

    public partial class MainService : ServiceBase
    {
        Logical.LogFile file;

        public MainService()
        {
            InitializeComponent();
        }

        protected override void OnStart(string[] args)
        {
            file = new LogFile();

            file.Write("OnStart");
        }

        protected override void OnStop()
        {
            file.Write("OnStop");

            file.Dispose();
        }

        protected override void OnPause()
        {
            file.Write("OnPause");
        }

        protected override void OnContinue()
        {
            file.Write("OnContinue");
        }
    }


Не забываем вставлять ссылку на библиотеку классов. Настраиваем установку службы.

Тестирование службы


Для финального тестирования возвращаемся к приложению Windows Form. Добавляем в него ссылку на созданную службу и создаем новый класс производный от класса описывающего созданную службу:

    class ServiceTest : MainService
    {
        public void TestStart(string[] args)
        {
            OnStart(args);
        }

        public void TestStop()
        {
            OnStop();
        }

        public void TestPause()
        {
            OnPause();
        }

        public void TestContinue()
        {
            OnContinue();
        }
    }

Создание этого класса позволяет нам вызывать методы службы из диалогового окна нашего приложения. Для примера — эмуляция старта службы:

        private void btStart_Click(object sender, EventArgs e)
        {
            service = new ServiceTest();

            service.TestStart(new string[0]);

            btStart.Enabled = false;
            btStop.Enabled = true;
            btPause.Enabled = true;
            btContinue.Enabled = false;
        }

После тестирования — можно разворачивать нашу службу.

Особенности служб Windows


Написав свою первую службу по работе с БД, столкнулся с загадочной ошибкой. При тестировании все работало замечательно, но периодически, при перезагрузке компьютера, служба не стартовала. Оказалось, что если сервер БД не успевал запуститься к моменту старта моей службы — возникала ошибка. Поэтому, когда пишите службу, необходимо понимать, какие приложения вы используете и будут ли они доступны в момент запуска службы

Ссылки


Полный текст решения.
Пример создания службы в msdn.
Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.