Programování služeb ve Windows - 2.díl
Pokračujeme 2. dílem o programování služeb Windows v C# .NET. Podepíšeme projekt vytvořeným klíčem (PokusnyKlic.snk):

Upravíme záložku ladění (pro tento případ stačí označit "Povolit ladění nespravovaného kódu", zde záleží na službě, kterou vytváříme.) Pokud označíme všechny záložky, na naši další činnost to nemá vliv!

Nastavíme adaptér síťového připojení (IPv6 možnost budoucího použití):

Nástroj SC (Sc.exe)
Každá služba musí být zapsána v databázi služeb a je uložena v registru.
- HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\jméno naší služby
- HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\eventlog\Application\jméno naší služby
První zápis je o údajích služby, druhý ukazuje na adresu dynamického helpu. Ve velké většině u služeb dodávaných mimo Windows ukazuje na .NET Framework. Registrace u Windows 7/8 je nutná, bez ní nebude služba funkční. Registraci služby a zápis do registru a DB služeb zabezpečuje nástroj Sc.exe .
Ke spuštění služby ve vzdáleném počítači lze sice použít nástroj Netsvc.exe nebo Instsrv.exe, avšak tyto nástroje neumožňují vzdáleně vytvořit novou službu. Nástroje zde uvedené jsou součástí sady Resource Kit.
Poznámka:
Nástroj Srvinstw.exe je verze nástroje pro vytváření
vzdálených služeb, která má grafické uživatelské rozhraní (GUI).
Srvinstw.exe není nástroj příkazového řádku. Popisy těchto nástrojů
jsou v přiloženém textu našeho projektu a v MSDN. Popis
Sc.exe. Popis Sc
config
Nástroj Installutil
Pomocí tohoto nástroje získáme možnost instalovat a odinstalovat službu. Tento nástroj najdeme ve složce: C:\Windows\Microsoft.Net\Framework. Musíme dát pozor na verzi .NET, kterou provádíme kompilaci (cílové rozhraní .NET). Musíte být přihlášeni jako administrátor Windows.
Postup, který se mi osvědčil, je následující. Zkopíruji soubory:
- Installutil.exe
- Installutil.exe.config
- installutilLib.dll
- cmd.exe (nemůže být zástupce)
do nově vytvořené složky Instal umístěné v ..\\Mojeservice\bin\Instal\ a vytvořím dva soubory Install.bat a Uninstall.bat.
Soubory ve složce Instal:
- cmd.exe
- InstallUtil.exe
- Installutil.exe.config
- installutilLib.dll
- Install.bat
- Uninstall.bat
Install.bat (obsahuje toto nastavení)
installutil.exe ..\Debug\TestService1.exe sc create Moje_Service_1 binPath=..\Debug\TestService1.exe type=own start=demand error=normal
Uninstall.bat (obsahuje toto nastavení)
sc delete Moje_Service_1 binPath=..\Debug\TestService1.exe installutil /u ..\Debug\TestService1.exe
Pokud spustíme příkaz Install.bat, vytvoří se v naší složce soubor MojeService.InstallLog, kde se bude zaznamenávat průběh instalace služby. Totéž provedeme s příkazem Uninstall.bat. Okno (cmd.exe) musíme spustit jako správce nebo musíme být přihlášeni jako administrátor. Pokud ne, dostaneme chybovou hlášku o nedostatečných právech a službu nezaregistrujeme. Pokud uživatel nebude mít práva "administrátor" a nebude skutečným administrátorem, službu nespustí. Na příklad uživatel "Pepa" má práva "uživatel" + "administrátor", toto se nerovná s právy účtu administrátor!!
Hlášení chyby v InstallUtilInstalLog :
Spouštění instalace s podporou transakcí: Zahajování instalační fáze instalace Prohlédněte si obsah souboru protokolu pro průběh sestavení ...\Služby\WindowsService1\WindowsService1\bin\Debug\TestService1.exe. Umístění souboru: ...\Služby\WindowsService1\WindowsService1\bin\Debug\MojeService.InstallLog. V průběhu instalační fáze došlo k výjimce. **System.Security.SecurityException** : Zdroj nebyl nalezen, ale některé nebo všechny protokoly událostí nelze prohledat. Nepřístupné protokoly: Security. ...další text.
Název našeho exe souboru může být libovolný, doporučuji pokud název změníme později ho neměnit, budeme poté měnit registrační soubory (náš název je TestService1.exe). Zadáme-li jiný název, upravíme Install.bat a Uninstall.bat.
Pokud se pokusíme naši šablonu spustit (MojeService1.exe z Visual Studia), je zobrazeno toto okno:

Od Windows7 je v jádru operačního systému rozšířené zabezpečení viz MSDN, potřebujeme práva administrátora.

Class Installer1 : System.Configuration.Install.Installer
Otevřeme Installer1 v okně kódu. Návrhář této třídě přiřadil pouze konstruktor. Třídu doplníme o kód.
[RunInstaller(true)] public partial class Installer1 : System.Configuration.Install.Installer { //Konstanty private const string DESKRIPTION = "Stručný komentář popis a účel služby "; private const string DISPLAYNAME = "Moje_Service_1"; private const string SERVICENAME = "MojeService1"; private ServiceInstallerDialog sid = new ServiceInstallerDialog(); //1 private ServiceInstaller serviceInstaller = new ServiceInstaller(); private ServiceProcessInstaller serviceProcessInstaller = new ServiceProcessInstaller(); public Installer1() { InstallServiceProcessInstaller(); InstallServiceInstaller(); InitializeComponent(); } //Informace o službách private void InstallServiceInstaller() { this.serviceInstaller.ServiceName = SERVICENAME; this.serviceInstaller.DisplayName = DISPLAYNAME; this.serviceInstaller.Description = DESKRIPTION; this.serviceInstaller.StartType = ServiceStartMode.Manual; this.serviceInstaller.Parent = this; } private void InstallServiceProcessInstaller() { this.serviceProcessInstaller.Account = ServiceAccount.LocalSystem; this.serviceProcessInstaller.Parent = this; this.serviceProcessInstaller.Password = null; //2 this.serviceProcessInstaller.Username = null; //3 } //Zde můžeme provádět kontrolu jména a hesla při Users módu . }
Pokud hlavní proces služby spouští více služeb, musíme přidat ServiceInstaller tolikrát, kolik služeb budeme spouštět.
- ServiceInstallerDialog nám zabezpečí, že při nastavení Account na User se zobrazí dialogové okno pro přihlášení. Musíme přidat odkaz na System.Windows.Forms.
- Musí být null
- Musí být null

Class MojeService1 : ServiceBase
Pro testování třídy MojeService1 ji vybavíme pomocnou funkcí, kterou po otestování můžeme odstranit. Pokud si věříte, tuto pasáž můžete vynechat. Tato funkce imituje funkčnost podřízených služeb.
Doplníme třídu tímto kódem:
public partial class MojeService1 : ServiceBase { // private ServiceA_1 service11; //reference na službu PerformanceCounter counter; System.Timers.Timer timer = new System.Timers.Timer(); string fileName; bool isStopping; protected override void OnStart(string[] args) { // vytvořit performance counter pro zjištění zatížení procesoru counter = new PerformanceCounter(); counter.CategoryName = "Processor"; counter.CounterName = "% Processor Time"; counter.InstanceName = "_Total"; // cesta, kam se budou data ukládat libovolný adresář musí existovat !!! // zápis musí být v tomto tvaru nesmí být ....\\temp\\.... fileName = @"c:\temp\cpu.txt"; // vytvořit timer, který bude každou vteřinu data zapisovat timer.Interval = 1000; timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed); timer.AutoReset = false; timer.Start(); } protected override void OnStop() { isStopping = true; } private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { // zastavuje se služba? pak neprovádět další krok if (isStopping) return; try { // naformátovat hlášku, která bude do logu zapsána string message = string.Format("{0:HH:mm:ss} - CPU usage {1}%", DateTime.Now, counter.NextValue()); // zapsat hlášku System.IO.File.AppendAllText(fileName, message + Environment.NewLine); } finally { // po provedení kroku znovu spustit časovač timer.Start(); } } }
Po spuštění ze složky Instalačni - cmd.exe - Install si můžeme prohlédnout spuštěnou službu. Musíme spustit v okně naší služby "Start".


Ukončíme službu tlačítkem "Stop", nebudeme provádět odinstalování příkazem Uninstall.bat!
Můžeme si oddechnout, první část máme za sebou, jedná se o rozcvičku. Může nás těšit, že tato část projektu je stejná u velké většiny služeb. Mění se pouze název služby.
Projekt ServiceControl
Tento projekt umožňuje sledovat a řídit služba systému Windows. Projekt není závislý na konkrétní naší službě, je použitelný obecně pro veškeré služby. Myslím, že je z dílny Microsoftu. Podle mne by tento projekt měl být rozšířen o zachycování chyb, je to na každém z vás.

Zdrojový kód neuvádím, je obsažen v projektu. Jedná se o okenní aplikaci exe.
Pokračování ve třetím díle.
Stáhnout
Stažením následujícího souboru souhlasíš s licenčními podmínkami
Staženo 118x (211.09 kB)
Aplikace je včetně zdrojových kódů v jazyce C#