Написание сервисной программы Win2000 с использованием Delphi
Аннотация: В этой статье рассказывается об использовании Delphi для написания сервисных программ Win2000. Используемые классы: TServiceApplicatoin, TService, TServiceThread и т. д.
Ключевые слова: Сервис/услуга
1. Знакомство со службами Win2000.
Приложение-служба — это фоновая программа, работающая в WinNT. Каждое приложение-служба может содержать несколько служб, и каждая служба является одним из потоков (служба также может создавать несколько подслужб). Используя службы, приложения могут получать специальные разрешения, и пользователь не будет напрямую завершать программу через диспетчер задач Win2000, поэтому службы часто используются для достижения некоторых особых целей.
С помощью инструмента управления службами на панели управления Win2000 мы можем устанавливать/просматривать характеристики службы:
(1) Имя службы (2) Отображаемое имя (3) Описание (4) Тип запуска; (5) Зависимости;
Среди них имя службы идентифицирует службу.
В качестве примера возьмем программу C:/WINNT/System32/services.exe для Win2000. Этот exe-файл соответствует приложению-службе и является видимым объектом служебной программы; exe-файл содержит несколько служб (служб), таких как Alerter, Клиент DHCP (DHCP), Messenger и т. д. Когда мы прекращаем работу службы, другие службы в Приложении-службе, в котором расположена служба, не прекращаются.
В Delphi инженеры Borland предоставляют нам классы TServiceApplication, TService, TServiceThread и другие, которые инкапсулируют большое количество деталей и упрощают разработку сервисных программ.
2. Приложение TService
В Delphi класс TServiceApplication соответствует вышеупомянутому ServiceApplication. Используя среду разработки Delphi, мы создаем новый Service Application PROject и создаем класс, унаследованный от TService. Объект Application в файле проекта является экземпляром TServiceApplication. Каждое TServiceApplication содержит несколько объектов TService, которые в точности соответствуют упомянутому выше количественному соотношению между сервисными программами и сервисами.
Прочитав определения классов TServiceApplication и TService, мы можем узнать, что TServiceApplication наследуется от класса TComponent, TService происходит от класса TDataModule, а объект Application отвечает за создание и уничтожение каждого объекта TService. Отследите следующий код
Приложение.CreateForm(TService1, Service1);
Можно обнаружить, что владельцами созданных объектов TService являются все объекты Application; в VCL FrameWork владелец всегда несет ответственность за уничтожение каждого объекта Component (класс TComponent VCL использует составной режим), поэтому TServiceApplication также будет уничтожать каждый объект TService.
Следуя коду TServiceApplication.Run, вы можете обнаружить, что TServiceApplication сначала анализирует рабочие параметры и реализует установку и удаление службы. Затем инициализируйте массив ServiceStartTable, который содержит имя службы и выполняющуюся запись каждого объекта службы; наконец, создайте объект TServiceStartThread, который является объектом потока, и вызовите API: StartServiceCtrlDispatcher из потока, чтобы запустить несколько служб, указанных в ServiceStartTable; Основной поток ServiceApplication продолжает зацикливаться и обрабатывать сообщения, например получать запросы на остановку/приостановку службы.
3. ТСервис
Класс TService наследуется от класса TDataModule, что означает, что мы можем добавить большое количество элементов управления VCL для достижения богатых функций. Кроме того, мы также можем обрабатывать OnStart, OnPause, OnStop, OnContinue, OnCreate, OnShutDown и другие события. Необходимо объяснить следующее: OnStop означает, что служба остановлена, а OnShutDown означает, что ServiceApplication прекратил работу, а это означает, что другие службы также были прекращены;
Как упоминалось ранее, ServiceApplication запускает каждую службу, вызывая StartServiceCtrlDispatcher. StartServiceCtrlDispatcher запускает вход TService, которым является TService.Main. TService.Main сначала регистрирует службу, а затем вызывает TService.DoStart. TService.DoStart создает внутренний объект-член TServiceThread, который является объектом потока; исследуя TServiceThread.Execute, мы можем знать, что когда мы обрабатываем TService1.OnExecute, TService будет делегировать все запросы объекту-члену TServiceThread для обработки. Метод по умолчанию обрабатывает все запросы.
TService.ServiceExecute — это основное содержимое TService. Чтобы служба работала нормально, помимо достижения целей, на которых ей необходимо сосредоточиться (например, прослушивание определенного порта, выполнение определенной задачи и т. д.), ей также необходимо отвечать на внешние команды/запросы: например, прекращение, приостановка и возобновление услуги. Поэтому вы можете рассмотреть возможность создания выделенного потока для выполнения этой задачи и обработки внешних команд/запросов в ServiceExecute. Итак, код выглядит следующим образом:
пока не прекращено, начинайте
ServiceThread.ProcessRequests(False);
конец;
Конечно, вы также можете выполнять определенные задачи в OnExecute, например прослушивание определенного порта, но это часто приводит к тому, что Служба не может своевременно отвечать на запросы «Стоп/Пауза» и другие запросы. Когда OnExecute завершен, служба фактически завершила свою задачу и вот-вот завершится (прекратит работу).
Ссылки:
MSDN, исходный код Delphi VCL, справочная документация Delphi.