Програмування служб Windows на Delphi
Шановні знавці!
Підкажіть, якщо хто займався:
1. Де можна подивитися
програмування служб Windows на Delphi з прикладами?
Може у вас є приклад?
2. Є додаток до форми. Як з нього зробити службу?
Із вдячністю # XA0; # XA0; # XA0; Леонід Федьків.
> Додаток до форми. Як з нього зробити службу?
Переробляти ж "одним махом" готове GUI-додаток в сервіс не тільки небажано, але і часто неможливо.
Ось ті приклад. File-> New-> Other-> Service application
uses
# XA0; Windows, Messages, SysUtils, Classes, Graphics, Controls, SvcMgr, Dialogs;
type
# XA0; TService1 = class (TService)
# XA0; # XA0; procedure ServiceExecute (Sender: TService);
# XA0; private
# XA0; # XA0;
# XA0; public
# XA0; # XA0; function GetServiceController: TServiceController; override;
# XA0; # XA0;
# XA0; end;
var
# XA0; Service1: TService1;
procedure ServiceController (CtrlCode: DWord); stdcall;
begin
# XA0; Service1.Controller (CtrlCode);
end;
function TService1.GetServiceController: TServiceController;
begin
# XA0; Result: = ServiceController;
end;
procedure TService1.ServiceExecute (Sender: TService);
begin
# XA0; # XA0; while not Self.Terminated do
# XA0; # XA0; # XA0; begin
# XA0; # XA0; # XA0; # XA0; ServiceThread.ProcessRequests (False);
# XA0; # XA0; # XA0; # XA0;
# XA0; # XA0; # XA0; # XA0; end;
# XA0; # XA0; # XA0; end;
end;
> Win-повідомлення
А ось як би з мінімальними зусиллями обмінюватися повідомленнями з делфовим service application? Я нічого кращого не придумав, чим створити невидиме вікно і йому повідомлення слати.
Не потрібно ніяких вікон.
Повідомлення м.б. послано не тільки вікна, а й нитки.
Див. PostThreadMessage ().
Єдине обмеження - асинхронність вищезгаданої ф-ції.
> Не потрібно ніяких вікон.
> Повідомлення м.б. послано не тільки вікна, а й нитки.
> Див. PostThreadMessage ().
> Єдине обмеження - асинхронність вищезгаданої
> Ф-ції.
В теорії я це знаю, а ось на практиці. Як отримати хендл потоку служби? Як в обробник повідомлень потоку вставити реакцію на призначене для користувача подія? Мова йде не про "службу з нуля", а про делфовом service application.
> Єдине обмеження - асинхронність вищезгаданої
> Ф-ції.
Трошки не зрозумів. А віконна функція - синхронна?
> Як отримати хендл потоку служби?
Для відправки повідомлення нитки потрібно не хендл, а ID нитки.
Нитка сервісу може записати свій ID, наприклад, в MMF.
> Як в обробник повідомлень потоку вставити реакцію на призначене для користувача
> Подія?
цикл слід організувати приблизно так (як варіант):
while not Terminated do begin
# XA0; WaitMessage;
# XA0; if PeekMessage (Msg, -1, TM_FIRST_MSG, TM_TM_LAST_MSG, PM_REMOVE) then
# XA0; # XA0; Dispatch (Msg.Message)
# XA0; else
# XA0; # XA0; ProcessRequests (False);
end;
> Віконна функція - синхронна?
Чи не віконна ф-ція, а ф-ція SendMessage ().
Вона поверне управління після обробки цільовим вікном посилається йому повідомлення, в той час як PostThreadMessage () посилає повідомлення і тут же повертає управління.
цікаво, чому так посилено ігнорітуют сокети, за допомогою яких можна дуже зручно реалізувати це саме спілкування? плюс - при бажанні - навіть віддалене адміністрування сервісу?
> Нитка сервісу може записати свій ID, наприклад, в MMF.
Так. А MMF - це що?
> Цикл слід організувати приблизно так
Це зрозуміло. Але як до цього дістатися в Service Application?
> Чи не віконна ф-ція, а ф-ція SendMessage ().
Зрозумів. Чи не зрозумів відразу, до чого синхронність відноситься.
Memory Mapped File
см. CreateFilemapping () + MapViewOfFile ()
> Як до цього дістатися в Service Application?
Подібний цикл повинен фігурувати в обробнику TService.OnExecute
Якщо не потрібно віддалене взаємодія з сервісом, то сокети тут навряд чи виправдані.
А якщо і потрібно, то за умови гомогенної сет.опер.среди розумніше використовувати NamedPipes. Та й в гетерогенної пайпи теж можна юзати - * nix-системи підтримують пайп-технологію.
> Memory Mapped File
Ясно. Просто з абревіатурою не стикався. Тільки ось MMF в даному випадку. Чи не з гармати по горобцях?
> Подібний цикл повинен фігурувати в обробнику TService.OnExecute
Ага. Спробую, спасибі.
> MMF в даному випадку. Чи не з гармати по горобцях?
Може і так.
Але в прогр.реалізаціі це простіше, ніж інші способи "публікування" подібного роду інф-ції.
Ось ще варіант "публікування". для головного вікна сервіс-додатки встановити св-во (див. SetProp), що являє собою рядок з текстовим поданням ID нитки сервісу. Тоді будь-який процес того ж робочого столу може знайшовши цікавить вікно прочитати це св-во (GetProp). Але це виправдано лише в разі коли сервіс-додаток реалізує один-єдиний сервіс, а не безліч сервісів (що цілком нормально).
Я б таки настійно рекомендував для інтерпроцессного взаємодії використовувати не механізм win-повідомлень, а іменування пайпи.
> Для однієї і тієї ж машини сокети мережа не смикають
Пайпи теж не "смикають". Зате не витрачають час на роботу аж ніяк не найшвидших транспортних протоколів на базі IP
> То краще робити взагалі кілька варіантів
Краще один зробити.
> Труби рулять. 0)
Ще не виявляється, що прога і на 98 винде працювати повинна. - (
> Така взаємодія клієнта і сервера через труби, а тут
> - бац! - з'ясовується, що під 98 це не йде.
Дик, його треба б було через безіменну трубу брати.
> Дик, його треба б було через безіменну трубу брати.
Що ж. Якщо ще така оказія трапиться - буду знати. -)
Win9x не реалізує лише серверний пайп-механізм, а пайп-клієнти там працюють цілком успішно.
Я в курсі. Але треба було, щоб клієнт і сервер могли працювати як на одній машині, так і на різних. Коротше, я про свій конкретний випадок, а не про "труби взагалі". ;-)