IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Programovanie služieb vo Windows - 3.díl

Ako ladiť služby?

Riešenie problémov je u služieb iné ako u ostatných aplikácií. Ako najlepší postup sa ukazuje najprv vytvoriť zostavenie s požadovanou funkčnosťou a testovacie klientsku aplikáciu ešte pred zavedením služby.

V tejto fáze je možné bezpečne ladiť a odstraňovať chyby. Po odladenie môžeme našu aplikáciu vložiť do služby. Akékoľvek chyby v službe sa nezobrazujú v okne správy, ale zapisujú sa do denníka udalostí. Službu nemôžeme spustiť v ladiacim programe, môžeme sa pripojiť k spustenému procesu služby. Postupujeme tak, že otvoríme vo VS zdrojový kód služby, nastavíme zarážky a pripojíme sa k bežiacemu procesu služby.

Z ponuky Ladenie vyberieme Pripojiť sa k procesu (Attach to Process) viď obrázok.

Pripojenie k procesu - C # - Pre pokročilých

Musíme vo vlastnostiach projektu označiť tieto políčka:

service Vlastnosti - C # - Pre pokročilých

Iný ďalší spôsob ladenie je uvedený na odkaze: programovanie-Windows-Services

Tu citujem z uvedeného článku.

Druhou možnosťou je priamo zavolať kód štartu služby, ak spustíte službu priamo z príkazového riadku. Napríklad ja používam ako odlíšenie testovacieho spustení parameter "debug". Kód v triede Program potom môže vyzerať takto:

static class Program
{
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    static void Main(params string[] args)
    {
        if (string.Equals(args.FirstOrDefault(), "debug", StringComparison.OrdinalIgnoreCase))
        {
            var service = new Service1();
            service.StartDebug();
            System.Threading.Thread.Sleep(System.Threading.Timeout.Infinite);
        }

        ServiceBase[] ServicesToRun;
        ServicesToRun = new ServiceBase[]
        {
            new Service1()
        };
        ServiceBase.Run(ServicesToRun);
    }
}

Tento kód kontroluje, či spúšťame aplikáciu s parametrom "debug" a ak áno, vytvorí inštanciu služby a vyvolá metódu na spustenie. Následne čaká nekonečnú dobu, vďaka ktorej sa aplikácia ihneď neukončí a my môžeme ladiť. Bez uvedenia parametra sa služba chová ako doteraz.

Aby mohlo toto riešenie fungovať, je ešte potrebné vystaviť metódu StartDebug pre triedu služby Service1. Metóda OnStart, ktorú chceme volať, totiž nie je verejná a nemôžeme ju zavolať priamo zo spúšťacej triedy Program.

internal void StartDebug()
{
    this.OnStart(null);
}

Teraz stačí len nastaviť pri ladení spúšťaní s parametrom "debug" vo vlastnostiach projektu:

Services_attach 2 - C # - Pre pokročilých

Toto riešenie je výhodné v jednoduchosti použitia. Program jednoducho spustíte priamo z Visual Studia s parametrom a môžete ladiť. Nevýhodou je, že spúšťanie služby len simulujeme. Pritom reálne spúšťanie služby systémom je trochu iné a beží v inom prostredí. Napríklad systém ju prideľuje iné oprávnenia a nedáva k dispozícii použitie užívateľského prostredia. (Koniec citátu)

Ďalšie možnosti sú popísané v MSDN, kto má záujem, môže si ich naštudovať.

Zavedený spôsob ladenie a testovanie služba

Podľa môjho je najlepší spôsob vytvorenia klienta a servera a tieto odladiť klasickým spôsobom a potom implementovať do služby. Je to zrejme najrýchlejší spôsob.

Tento spôsob som nevymyslel, jeho stratégiu načrtla mnoho autorov predo mnou a ja som tento spôsob tiež prevzal. Nie je nutné mať práva administrátora pre pohodlné ladenie a testovanie.

  • Vytvoríme projekt servera (čo nám bude naša služba vykonávať)
  • Okenné jednoduchú aplikáciu pre spustenie servera
  • Okenné aplikáciu pre sledovanie činnosti servera nemusíme prepínať do "Prehliadače udalostí"
  • Jednoduchého klienta pre komunikáciu

Tu by som chcel upozorniť, že vnútorné funkcie sa budú líšiť podľa zamerania servera a výmeny dát.

Server našej služby

Funkčnosť servera bude otvoriť súbor, načítať náhodne dáta zo súboru a táto náhodná dáta poslať na klienta pomocou IP. Udalosti budeme zapisovať v systémovom logu, môžeme trastovat a používať počítadlá výkonu.

Pridáme do nášho projektu ďalší projekt, ktorý pomenujeme na príklad Server, na mene nezáleží.
VS - súbor - pridať - nový projekt - Windows - knižnica tried (názov projektu Server).
Visual štúdio nám neumožňuje vytvoriť (.dll) projekt priamo z komponenty, preto je jednoduchšie toto obísť. Teraz pridáme do nášho nového projektu komponent, nazveme ju MujServer1 a ak nebudeme potrebovať pre veľkú zložitosť triedu, tak túto predchádzajúcu triedu odstránime.

Náš kód servera bude vyzerať:

public partial class Server1 : Component
{
    public Server1(IContainer container)
        {
            container.Add(this);
            InitializeComponent();
        }
}

Postupne doplním a vysvetlím kód. Vykonáme kompiláciu iba tohto projektu na získanie dll knižnice.

Projekt test servera

Ďalší projekt pridaný do našej aplikácie bude jednoduchá konzolová aplikácia, ktorá bude simulovať štart a ukončenie služby. Názov môže byť ľubovoľný. VS - súbor - pridať - nový projekt - konzolová aplikácie, pomenujeme TestServeru.

using System;
namespace WindowsService1
{
    class Program
    {
        static void Main(string[] args)
        {
            Server1 qs = new Server1(@"C:\Temp\quotes.txt", 4567); //1 , 2 , 3
                    qs.Start();
                    Console.WriteLine("Pro ukončení stiskněte klávesu Enter.");
                    Console.ReadLine();
                    qs.Stop();
        }
    }
}
  1. @ "C: \ Temp \ quotes.txt" je umiestnenie nášho testovacieho súboru, musí existovať.
  2. Názov súboru musí byť plná cesta, nesmie sa používať dvojitá lomky!
  3. Port bude rovnaký pre všetky inštalácie.
  4. Pridáme odkaz na náš server. (Knižnica MujServer.dll)

Tu nebudeme už nič meniť, všetko je jasné.

Projekt MujServerEven­tListener

Tento projekt bude sledovať všetky naše udalosti, ako pri ladení servera mimo inštalácii tak i pri celkovom ladení, keď bude začlenený do nášho inštalačného projektu. Toto je pohodlné, prepínanie do logovanie je nepraktické a zdĺhavé. Udalosti sa zapisujú tak ako sú vyvolané.
Vs - pridať - nový projekt - Formulárová aplikácie Windows (názov MujServerEven­tListener)
Kód tejto aplikácie je tiež veľmi jednoduchý:

using System;
using System.Windows.Forms;

namespace WindowsService1
{
    partial class MujServerEventListener : Form
    {
        public MujServerEventListener()
        {
            InitializeComponent();
            eventLog1.EnableRaisingEvents = true;
            eventLog1.Log = "Application";
            eventLog1.MachineName = ".";
            eventLog1.Source = "MojeService1";
    }
        protected void OnEntryWritten(object sender, System.Diagnostics.EntryWrittenEventArgs e)
        {
            DateTime time = e.Entry.TimeGenerated;
            string message = e.Entry.Message;
            this.listBox1.Items.Add(time + " " + message);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }
    }
}

Otvoríme návrhár zobrazenie a pretiahneme na plochu komponent EventLog. Upravíme zdroj udalostí.
Nezabudneme pridať referencie na server.

Projekt CLIENTSERVER

Tento posledný projekt bude odosielať a prijímať dáta zo servera.
Vs - pridať - nový projekt - Formulárová aplikácie Windows (názov CLIENTSERVER).

Kód tejto aplikácie je tiež veľmi jednoduchý:

using System;
using System.Windows.Forms;
using System.Text;
using System.Net.Sockets;

namespace WindowsService1
{
    partial class ClientServer1 : Form
    {
        public ClientServer1()
        {
            InitializeComponent();
        }

        private void OnGetQuote1_Click(object sender, EventArgs e)
        {
            TcpClient client = new TcpClient();
            NetworkStream stream = null;
            try
            {
                client.Connect("127.0.0.1", 5678);          //1
                stream = client.GetStream();                //2
                byte[] buffer = new Byte[1024];
                int received = stream.Read(buffer, 0, 1024);        //3
                if (received <= 0)
                {
                    this.textQuote1.Text = "Čtení selhalo";
                    return;
                }
                textQuote.Text = Encoding.Unicode.GetString(buffer);    //4
            }
            catch (SocketException ex)
            {
                this.textQuote1.Text = ex.Message;
            }
            finally
            {
                if (stream != null)
                    stream.Close();                 //5
                if (client.Connected)
                    client.Close();                 //5
            }
        }
    }
}
  1. Pripojenie klienta k vzdialenému hostiteľovi TCP pomocou zadaného hostiteľa, mená a čísla portu.
  2. Vráti NetworkStream, slúži na odosielanie a prijímanie dát.
  3. Čítanie dát z NetworkStream.
  4. Kódovanie UTF-16 formáte little-endian bajt poradí načítanie.
  5. Zatvorí aktuálny prúd a uvoľní všetky prostriedky (napríklad sokety a popisovačov súboru) spojené s aktuálnym dátovým prúdom.
windows Service - C # - Pre pokročilých

Doplníme assemblyInfo:

CLIENTSERVER, MujServerEven­tListener, Server a WindowsService1.

using System.Security;

[assembly: AssemblyKeyNameAttribute("")]
[assembly: SecurityRules(SecurityRuleSet.Level2)]

Ak používate VS2008 .NET Framework nižšia ako verzia 4.0 použijete:

[assembly: SecurityRules(SecurityRuleSet.Level1)]

Pri všetkých projektov vo vlastnostiach - zostavenie - spracovávať upozornenie ako chyby - zaškrtneme všetko

Budeme pokračovať v ďalšom dieli doplnením kódu servera.


 

Stiahnuť

Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami

Stiahnuté 79x (306.77 kB)
Aplikácia je vrátane zdrojových kódov v jazyku C#

 

Všetky články v sekcii
C # - Pre pokročilých
Článok pre vás napísal zpavlu
Avatar
Užívateľské hodnotenie:
Ešte nikto nehodnotil, buď prvý!
C# , C++ a assembler
Aktivity