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.
Musíme vo vlastnostiach projektu označiť tieto políčka:
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:
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(); } } }
- @ "C: \ Temp \ quotes.txt" je umiestnenie nášho testovacieho súboru, musí existovať.
- Názov súboru musí byť plná cesta, nesmie sa používať dvojitá lomky!
- Port bude rovnaký pre všetky inštalácie.
- Pridáme odkaz na náš server. (Knižnica MujServer.dll)
Tu nebudeme už nič meniť, všetko je jasné.
Projekt MujServerEventListener
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
MujServerEventListener)
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 } } } }
- Pripojenie klienta k vzdialenému hostiteľovi TCP pomocou zadaného hostiteľa, mená a čísla portu.
- Vráti NetworkStream, slúži na odosielanie a prijímanie dát.
- Čítanie dát z NetworkStream.
- Kódovanie UTF-16 formáte little-endian bajt poradí načítanie.
- 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.
Doplníme assemblyInfo:
CLIENTSERVER, MujServerEventListener, 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#