Создание сервиса в Visual Studio 2008

Службы Windows – приложения, автоматически запускаемые системой при запуске системы и выполняющие вне зависимости от статуса пользователя (wikipedia). Службы можно разделить на два типа:

  • службы Win32, взаимодействующие с операционной системой посредством диспетчера управления службами
  • драйвера, работающие по протоколу драйвера устройства.
    В данной статье мы рассмотрим службы Win32.

Windows предлагает программу Service Control Manager (SCM) с помощью которой можно управлять созданием, удалением, запуском и остановкой служб. Приложения, имеющее статус сервиса, должно быть написано таким образом, чтобы оно могло принимать сообщения от SCM. Службы работают в фоновом режиме и их работа скрыта от пользователя. Поэтому они идеально подходят для реализации серверных процессов в приложениях построенных по принципу клиент-сервер, сетевых служб, программ мониторинга и т.д.

Давайте создадим службу в Visual Studio. Для этого File->New->Project. Тип проекта выбираем Windows и в шаблонах выбираем Windows Service (рис. 1). Назовем наш сервис MyService, в Location определим директорию в которой будем сохранять наш проект.

Рис. 1 Создание проекта

После создания проекта настроим наш сервис. Для этого во вкладке свойств (Properties) установим следующие значения Name -> MyService чтобы наш класс назывался так же как и наш проект (при создании проекта, класс по умолчанию получает имя Service1). AutoLog -> true, в случае, если оно false. Service Name -> My First Service или любое имя на ваш вкус.

Рис. 2 Свойства сервиса

Теперь займемся функциональностью нашего сервиса. Мы создадим простой сервис, который будет писать в файл некоторую информацию при старте и останове нашего сервиса, а также записывать текущую дату и время каждые 5 секунд. Для этого в файле Service1.cs добавим пространство имен System.IO и объявим скрытое поле StreamWriter logFile:

...
using System.IO;

namespace MyService
{
   public partial class MyService : ServiceBase
   {
      StreamWriter logFile;
      ...

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

...
System.Timers.Timer timer;
...

Обратите внимание, что студия автоматически создала обработчики событий OnStart() и OnStop(), которые отвечают за события запуска и останова службы. Также можно реализовать события OnPause (пауза), OnContinue (продолжить выполнение). Давайте наполним функциональностью события запуска и останова OnStart() и OnStop()

protected override void OnStart(string[] args)
{
   //создадим файл на диске C:\MyServiceLog.txt
   logFile = new StreamWriter(new FileStream(@"C:\MyServiceLog.txt", FileMode.Append));
   //запишем статус сервиса
   logFile.WriteLine("My First Service стартовал...");
   logFile.Flush();

   //инициализируем таймер
   timer = new System.Timers.Timer();
   timer.Enabled = true;
   //задаем период 5 секунд
   timer.Interval = 5000;
   //подписываемся на событие
   timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
}

 

protected override void OnStop()
{
   //останавливаем таймер
   timer.Enabled = false;
   //запишем статус сервиса
   logFile.WriteLine("My First Service остановлен");
   logFile.Flush();
   logFile.Close();
}
<p style="text-align: justify;">

В событии таймера Elapsed записываем конкретную дату и время:

void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
   logFile.WriteLine(DateTime.Now.ToString());
   logFile.Flush();
}

С функциональностью нашего сервиса мы разобрались. Теперь нужно подумать об установке. Для этого чтобы необходимо создать установщик. Переходим на вкладку Service1.cs[Design] и кликаем правой кнопкой мыши. В контекстном меню выбираем Add Installer (рис. 3) или на вкладке Properties кликаем Add Installer (рис. 4)


Рис. 3 Добавление установщика


Рис. 4 Добавление установщика

В нашем проекте появился файл ProjectInstaller.cs в котором храниться класс компонента с двумя установщиками:

  • ProjectInstaller  – для установки служб
  • ServiceInstaller – для установки связанного со службой процесса.

На вкладке ProjectInstaller.cs[Desig] выбираем ServiceInstaller и изменяем его свойтва на вкладке Properties:
NameMyService
StartTypeAutomatic

Рис. 5 Свойства ServiceInstaller1

Для ServiceProcessInstaller1 изменим значение Acount на LocalSystem (рис. 6)

Рис. 6 Свойства ServiceProcessInstaller1

Следующим нашим шагом будет создание исполняемого файла для нашей службы. Для этого в Solution Explorer кликаем правой на название нашего проекта и выбираем пункт Properties. В появившемся диалоговом окне на вкладке Application для пункта Startup object устанавливаем значение MyService.Program (рис. 7)

Рис. 7 Установка свойств для программы установки

Дальше на нужно собрать наш проект, для этого Build -> Build Solution или просто нажать клавишу F6. В результате этого в директории проекта bin\Debug или bin\Release будет создан файл MyService.exe. При попытке запустить файл система выдаст сообщение

Рис. 8 Сообщение о необходимости установки сервиса

Система сообщает нам о том, что “Невозможно запустить службу из командной строки или отладчика. Сначала требуется установить службу Windows (с помощью installutil.exe), а затем ее следует запустить, используя программу ServerExplorer, средство администрирования служб Windows или команду NET START.”

Давайте это исправим. Для этого, нам необходимо создать проект установки для службы. Переходим в меню File -> Add -> New Project. В появившемся диалоговом окне выбираем тип проекта Other Project Types ветвь Setup and Deployment, в окне шаблонов Setup Project и задаем имя проекта (рис. 9).

Рис. 9 Добавление проекта установки для службы

Проект установки добавлен. На вкладке File System(MyServiceSetup) мы можем видеть сборку файлов для установки File System on Target Machine (рис. 10).

Рис. 10 Создание проекта установки

Следующим нашим шагом будет определение директории проекта нашей службы. Правой кнопкой мыши кликаем на узел File System on Target Machine -> Add Special Folder -> System Folder (рис. 11)

Рис. 11 Добавление System Folder

В контекстном меню System Folder выбираем Add -> Project Output -> Primary output

Рис. 12 Primary Output

Рис. 13 Add Project Output Group

Для нашего проекта установки необходимо определить действия. Для этого вызываем контекстное меню для проекта MyServiceSetup пункт View -> Custom Action (рис. 14).

Рис. 14 Определение действий инсталлятора

Появилась вкладка Custom Action(MyServiceSetup) в которой по умолчанию присутствуют четыре действия: Install, Commit, Rollback, Uninstall. Для Install и Uninstall через их контекстные меню вызовем пункт Add Custom Action и укажем System Folder -> Primary output from MyService (Active). Теперь соберем проект для инсталлятора. Вызовем для узла MyServiceSetup пункт Build или нажав сочетание клавиш Shift+F6 для сборки активного проекта.

Теперь осталось установить наш сервис. Для этого, вызываем контекстное меню для нашего проекта установки MyServiceSetup и выбираем пункт Install. В результате будет запущен Setup Wizard, на втором шаге указываем директорию для установки С:\Windows\System32. Также, службу можно устанавливать и удалять, используя файлы setup.exe и MyServiceSetup.msi, которые находятся в папке проекта инсталлятора. В нашем случае D:\…\MyService\MyServiceSetup\Debug (или …\Release). Удалять службу можно используя мастер установки и удаления программ (Пуск -> Настройки -> Панель управления -> Установка и удаление программ).

Для управления службой необходимо открыть диспетчер управления службами (Пуск -> Настройка -> Панель управления -> Администрирование -> Службы или же из командной строки набрав services.msc). Имя нашей службы My First Service будет отображено в открывшемся окне. Службу можно запустить обычным образом через контекстное меню, вызвав пункт Пуск. После запуска, наша служба создала файл C:\MyserviceLog.txt и записал в него информацию о том, что он запустился. Каждые 5 секунд, он будет записывать текущую дату и время.
Возможное содержимое фала:

[download id=”3″]

11 Comments

  1. Добрый день!
    Вопрос по обновлению службы. Если я меняю версию сборки и пытаюсь вновь установить службу, то установщик выдает что такая служба уже есть и файл службы не обновляет. Как можно обновлять службу не вызывая сначала деинсталяцию?
    Спасибо.

  2. а можете ли вы отобразить всю программу сразу(т.е. код программы)

  3. На нашёл службу в списке.
    И проект не качается…

  4. В студии нет такого шаблона, где его можно скачать?

Leave a Reply

Your email address will not be published. Required fields are marked *

http://csharpcoding.org/wp-content/plugins/wp-monalisa/icons/wpml_bye.gif  http://csharpcoding.org/wp-content/plugins/wp-monalisa/icons/wpml_good.gif  http://csharpcoding.org/wp-content/plugins/wp-monalisa/icons/wpml_negative.gif  http://csharpcoding.org/wp-content/plugins/wp-monalisa/icons/wpml_scratch.gif  http://csharpcoding.org/wp-content/plugins/wp-monalisa/icons/wpml_wacko.gif  http://csharpcoding.org/wp-content/plugins/wp-monalisa/icons/wpml_yahoo.gif 
http://csharpcoding.org/wp-content/plugins/wp-monalisa/icons/wpml_cool.gif  http://csharpcoding.org/wp-content/plugins/wp-monalisa/icons/wpml_heart.gif  http://csharpcoding.org/wp-content/plugins/wp-monalisa/icons/wpml_rose.gif  http://csharpcoding.org/wp-content/plugins/wp-monalisa/icons/wpml_smile.gif  http://csharpcoding.org/wp-content/plugins/wp-monalisa/icons/wpml_whistle3.gif  http://csharpcoding.org/wp-content/plugins/wp-monalisa/icons/wpml_yes.gif 
http://csharpcoding.org/wp-content/plugins/wp-monalisa/icons/wpml_cry.gif  http://csharpcoding.org/wp-content/plugins/wp-monalisa/icons/wpml_mail.gif  http://csharpcoding.org/wp-content/plugins/wp-monalisa/icons/wpml_sad.gif  http://csharpcoding.org/wp-content/plugins/wp-monalisa/icons/wpml_unsure.gif  http://csharpcoding.org/wp-content/plugins/wp-monalisa/icons/wpml_wink.gif