Programování služeb ve Windows - 2.díl

C# .NET Pro pokročilé 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):

Podepsání aplikace vytvořeným klíčem.

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!

Uprava nutná pro ladění service

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

Síťové připojení

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.

  1. HKEY_LOCAL_MAC­HINE\SYSTEM\Cu­rrentControlSet\ser­vices\jméno naší služby
  2. HKEY_LOCAL_MAC­HINE\SYSTEM\Cu­rrentControlSet\ser­vices\eventlog\Ap­plication\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\Mi­crosoft.Net\Fra­mework. 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.e­xe.config
  • installutilLib.dll
  • cmd.exe (nemůže být zástupce)

do nově vytvořené složky Instal umístěné v ..\\Mojeservi­ce\bin\Instal\ a vytvořím dva soubory Install.bat a Uninstall.bat.

Soubory ve složce Instal:

  • cmd.exe
  • InstallUtil.exe
  • Installutil.e­xe.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.In­stallLog, 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 InstallUtilIn­stalLog :

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:

Chyba spuštění

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

Spuštění bez práv administrátora

Class Installer1 : System.Configu­ration.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.

  1. ServiceInstaller­Dialog 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.Window­s.Forms.
  2. Musí být null
  3. Musí být null
Installer User

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".

Instaler
Testovací soubor

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.

Kontrola služeb

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ženo 80x (211.09 kB)
Aplikace je včetně zdrojových kódů v jazyce C#

 

  Aktivity (1)

Článek pro vás napsal zpavlu
Avatar
C# a C++

Jak se ti líbí článek?
Ještě nikdo nehodnotil, buď první!


 


Miniatura
Všechny články v sekci
C# - Pro pokročilé

 

 

Komentáře

Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zatím nikdo nevložil komentář - buď první!