07.09.2014, Vladimír Klaus, navštíveno 10231x
Co to je služba neboli service
Služba je malý program, který běží na pozadí a může vykonávat různé užitečné služby, jako je třeba pravidelná kontrola aktualizací, logování chování uživatele, odesílání změn v datech do cloudu apod. Možností je opravdu nepřeberně, na počítači bývá nainstalováno i několik stovek služeb.
Vytvoření služby
Zvolte z menu File > New > Other > Delphi Projects a vyberte Service Application.
Projekt i vytvořený formulář uložte, třeba jako Main.pas a AudreyTestService.dproj. Formuláři ještě nastavte jména, abyste pak mohli službu lépe identifikovat. Je důležité si uvědomit, že název, pomocí, kterého se budete na službu odkazovat je AudreyTestServiceMain, nikoli pomocný popis „AUDREY Test Service“.
Nyní už jen proveďte kompilaci a je to. Tedy skoro, nyní je nutné službu nainstalovat, protože ji nelze jen tak spustit poklepáním na exe soubor.
Instalace a odinstalace služby
K instalaci stačí zavolat program s parametrem /install.
c:\Test\AudreyTestService.exe /install
Pokud už je služba nainstalována, objeví se tato chyba.
Před novou instalací musíte proto službu odinstalovat.
c:\Test\AudreyTestService.exe /uninstall
To, že je služba nainstalována ale neznamená, že běží. V jakém stavu služba je, si můžete ověřit ve Správci úloh na záložce Služby.
Pokud potřebujete službu nainstalovat nebo odinstalovat tiše (bez závěrečného dialogu), můžete ještě přidat přepínač „silent“, tedy třeba takto:
c:\Test\AudreyTestService.exe /install /silent
Práce se službou
Aby služba něco dělala, musí být spuštěná, to se provádí z příkazové řádky takto:
net start "AUDREY Test Service"
nebo
net start AudreyTestServiceMain
Všimněte si, že už se nezadává název exe souboru, ani cesta, ale jen název nebo popis služby, který jsme si na začátku zvolili. Název je v uvozovkách, protože obsahuje mezery, ale jinak to není potřeba.
Službu můžete také zastavit, což je třeba, když chcete vytvořit novou verzi. Nebo jí jen pozastavit a pak zase spustit. Slouží k tomu tyto příkazy.
net stop "název služby"
net pause "název služby"
net continue "název služby"
Službu můžete pochopitelně obsluhovat také přímo z kontextového menu Správce úloh.
Aby služba něco dělala
Službu máte nainstalovanou i spuštěnou, ale zatím nic nedělá. Přidáme jednouché logování aktuálního času každé 2 minuty.
Na hlavní formulář přidejte TTimer, nastavte interval na „2 minuty“ a hlavně nezapomeňte nastavit Enabled na false, aby nebyl časovač hned spuštěn. Časovač spustíme až později.
Nejprve si napíšeme logovací proceduru. Funkce na přidávání textu do souboru „AppendAllText“ je v IOUtils. Má tu výhodu, že pokud soubor neexistuje, tak ho nejprve založí, jinak jen přidá zadaný text na jeho konec.
uses IOUtils;
procedure TAudreyTestServiceMain.Log(aText: string);
begin
TFile.AppendAllText('c:\Log.txt', aText+#13#10, TEncoding.ANSI);
end;
Poklepáním na časovač přidáme logovací akci, která se bude pravidelně vykonávat.
procedure TAudreyTestServiceMain.Timer1Timer(Sender: TObject);
begin
Log(DateTimeToStr(Now));
end;
Nyní si zkusíme službu přeložit, ale i když je vše v pořádku, tak to přeložit „nejde“. Důvodem je to, že služba běží a není možné přepsat AudreyTestService.exe. Službu tedy nejprve zastavte, odinstalace ale není nutná!
Kompilace je nyní už možná a i když službu znovu spustíte, stále nebude nic dělat. Ještě nám totiž chybí doprogramovat tu hlavní výkonnou část. Zobrazte si formulář, přepněte na Events a poklepejte na OnExceute.
To je procedura, která se vykoná při spuštění služby. V našem případě zapneme časovač a pak se už jen čeká, než službu někdo zastaví. Pokud se tak stane, časovač vypneme.
procedure TAudreyTestServiceMain.ServiceExecute(Sender: TService);
begin
Timer1.Enabled := True;
while not Terminated do
ServiceThread.ProcessRequests(True); // čekáme na ukončení
Timer1.Enabled := False;
end;
Vlastní práci (logování) tedy odvádí pravidelné spuštění akce časovačem a služba jako taková v podstatě nic nedělá – jen čeká na své ukončení.
Nyní znovu program přeložte a pak službu spusťte. Za pár minut najdete v souboru c:\Log.txt něco takového.
Další události služby
U služby můžete reagovat i na další události, jako je třeba, co se stane při zastavení, po instalaci, před odinstalací apod. Program tedy ještě trochu rozšíříme.
procedure TAudreyTestServiceMain.ServiceStart(Sender: TService; var Started: Boolean);
begin
Log('Spuštění služby - '+DateTimeToStr(Now));
end;
procedure TAudreyTestServiceMain.ServiceStop(Sender: TService; var Stopped: Boolean);
begin
Log('Zastavení služby - '+DateTimeToStr(Now));
end;
procedure TAudreyTestServiceMain.ServiceAfterInstall(Sender: TService);
begin
Log('Služba byla nainstalována - '+DateTimeToStr(Now));
end;
procedure TAudreyTestServiceMain.ServiceAfterUninstall(Sender: TService);
begin
Log('Služba byla odinstalována - '+DateTimeToStr(Now));
end;
Logovací soubor pak může vypadat nějak takto.
Co se vám bude hodit
Určitě to bude program SC, který slouží ke komunikaci se službami. Takto se třeba dozvíte, v jakém stavu služba je. Může se také hodit stručný popis programu SC.
Hodně pěkné a podrobné povídání o programování služeb v Delphi najdete pak v tomto článku.
Jaká jsou zde omezení
I když příprava programu ve formě služby vypadá stejně, jako u běžné aplikace, není tomu tak. První věcí, které se musíte vyhnout, jsou jakékoliv dialogy a interakce s uživatelem. To z principu není téměř možné, tedy pokud se nechcete ponořit do interaktivních služeb.
Dále musíte dávat pozor na to, kdo službu instaloval, kdo ji používá apod. Na novějších Windows se pracuje s právy a je možné, že běžnému uživateli služba nepoběží, nebude ji moci nainstalovat nebo nebude (zdánlivě) fungovat. Příklad může být zápis do logu, ke kterému není přístup. Ale protože služba žádnou chybovou hlášku nezobrazí, nebude o tom nikdo vědět.
Závěr
Toto byl malý úvod do vytvoření služby. Pokud se vám nechce toto vše psát, můžete si stáhnout hotový program z této stránky. Jestliže budete chtít službu ladit, je to už trochu pracnější, stejně tak jako vytvoření programu, který může běžet jako služba i jako běžná aplikace.