Pagkakaiba sa pagitan ng isang serbisyo at isang aplikasyon. Aling mga serbisyo ng Windows ang kailangan at alin ang maaaring hindi paganahin. Ang paglitaw ng mga serbisyong nakabatay sa trigger

Mula sa punto ng view ng pagiging tugma ng software. Kaya natural lang na bumalik tayo sa pagtalakay sa mga serbisyo sa konteksto ng Windows 7. Ngunit sa pagkakataong ito ay pag-uusapan natin ang ilan sa mga benepisyo ng pag-optimize ng mga serbisyong available sa Windows 7. Ang artikulong ito ay tungkol sa isang bagong feature sa Windows 7 - Trigger Start Services. Ngunit bago natin tingnan ang API, tingnan natin ang malaking larawan ng mga serbisyo.

Ano ang mga serbisyo?

Ang isang serbisyo ay isang panloob na mekanismo na binuo sa Windows operating system. Maaari mong isipin ang mga serbisyo bilang mga espesyal na application na tumatakbo anuman ang kasalukuyang konteksto ng user. Iba ang mga serbisyo sa mga regular na application dahil maaari silang i-configure upang gumana mula sa sandaling naka-on ang system (na-boot) hanggang sa pag-shutdown, nang hindi nangangailangan ng presensya ng user. Ibig sabihin, maaaring tumakbo ang mga serbisyo kahit na hindi naka-log in ang user.

Mas gusto naming isipin ang mga serbisyo bilang pagpapatakbo ng mga gawain na tumatakbo sa background at hindi nakakaapekto sa mga operasyon ng user. Ang mga serbisyo sa Windows ay responsable para sa lahat ng uri ng aktibidad sa background, mula sa Remote Procedure Call (RPC), Printer Spooler at hanggang sa Network Location Awareness.

Sa paglipas ng mga taon, ang Windows ay lumago at gayon din ang bilang ng mga serbisyo. Tayo'y maging tapat, ang mga serbisyo sa background sa Windows ay medyo masakit - ang operating system ay may kasamang maraming serbisyo sa labas ng kahon. Bilang karagdagan, ang mga independiyenteng software developer (ISV) at ang kanilang mga application ay nagdaragdag ng higit pang mga serbisyo. Halimbawa, mga serbisyo sa pag-update ng software. Gayunpaman, ang ilang mga serbisyo ay kritikal at kinakailangan sa panahon ng proseso ng pag-boot, habang ang iba ay kinakailangan sa ibang pagkakataon kapag ang isang partikular na user ay nag-log in, at ang iba ay hindi kailangang magsimula sa lahat hanggang sa sila ay tinatawag. Sa kabila nito, kapag tiningnan mo ang listahan ng mga kasalukuyang tumatakbong serbisyo, makikita mo ang maraming bagay na hindi kailangang gumana nang 24x7.

Ano ang mali sa mga serbisyong gumagana 24 oras sa isang araw, 7 araw sa isang linggo?

Mayroong ilang mga problema na nauugnay sa mga serbisyong 24x7. Una, bakit dapat tumakbo ang isang bagay (kahit sa background) kung hindi ito kailangan? Ang anumang tumatakbong proseso (kabilang ang mga serbisyo) ay gumagamit ng mahalagang memorya at mga mapagkukunan ng CPU na maaaring magamit para sa iba pang mga application at serbisyo. Kung bibilangin mo ang lahat ng serbisyong tumatakbo sa isang partikular na sandali, magdadagdag ang mga ito ng malaking halaga ng memory, handle, thread, at paggamit ng CPU. Ang lahat ng "nasayang" na mapagkukunang ito ay binabawasan ang pangkalahatang pagganap ng computer, binabawasan ang pagtugon nito, at ginagawang mabagal at mabagal ang computer. Bilang karagdagan, dahil maraming mga serbisyo ang na-configure upang awtomatikong magsimula (magsimulang gumana kapag nagsimula ang system), nakakaapekto ang mga ito sa oras ng pag-boot ng computer.

Pangalawa, ang mga nasayang na mapagkukunan na ito ay may direktang epekto sa pagkonsumo ng enerhiya. Kung mas malaki ang load sa CPU, mas maraming kapangyarihan ang natupok ng computer. Maaari itong maging kritikal sa mga laptop at maaaring mabawasan ang buhay ng baterya ng ilang oras.

Pangatlo, ang patuloy na pagpapatakbo ng hindi produktibong software ay maaaring humantong sa mga pagtagas ng memorya at pangkalahatang kawalang-tatag ng system. Ito ay humahantong sa pagkabigo ng mga application at, sa huli, ang computer.

Sa wakas, kung ang serbisyo ay nagpapatakbo ng 24x7, at kung ito ay isang kilalang serbisyo (na maaaring mayroon ang bawat sikat na application, gaya ng PDF Reader), kung gayon ito ay lumilikha ng isang malaking pag-atake. Ang isang umaatake ay maaaring gumamit ng impormasyon na ang isang partikular na sikat na application ay nag-i-install ng isang 24x7 na serbisyo at subukang i-hack ito upang makakuha ng access sa computer.

Sa lahat ng sinabi, maaaring nagtataka ka kung bakit napakaraming developer ang nagse-set up ng kanilang mga serbisyo upang tumakbo sa lahat ng oras kung mayroon silang isa pang opsyon. Kahit na bago ang Windows 7, mayroong ilang mga opsyon na magagamit upang simulan ang mga serbisyo:

  • Hindi pinagana ganap na hindi pinapagana ang isang serbisyo at pinipigilan ito at mga umaasa na serbisyo mula sa pagsisimula - ibig sabihin ay dapat manual na paganahin ng user ang serbisyo mula sa Control Panel o Command Prompt
  • Manwal nagsisimula ng isang serbisyo kung kinakailangan (dahil sa mga dependency ng iba pang mga serbisyo) o kapag ang serbisyo ay tinawag mula sa application gamit ang naaangkop na mga API, tulad ng ipapakita sa ibaba
  • Awtomatiko magsisimula ng serbisyo sa pag-log in
  • Awtomatikong Naantala– isang mas bagong uri ng startup na ipinakilala sa Windows Vista, kung saan magsisimula ang serbisyo pagkatapos makumpleto ang boot at makumpleto ang mga paunang operasyon, na nagpapabilis sa pagsisimula ng system.

Sa kasamaang palad, maraming ISV (kabilang ang Microsoft mismo) ang patuloy na nagtakda ng kanilang mga serbisyo sa Automated o Automatic Delayed dahil ito ang pinakasimpleng solusyon para sa lahat. Ang serbisyo ay tumatakbo nang 24x7 at palaging magagamit, inaalis ang anumang pangangailangan upang suriin ang mga dependency o kung ang serbisyo ay tumatakbo.

Maraming mga halimbawa ng mga kasalukuyang serbisyo na maaaring gumamit ng mas kaunting mga mapagkukunan at maging mas ligtas nang hindi gumagana nang 24x7. Halimbawa, isipin ang tungkol sa isang serbisyo sa pag-update na tumitingin ng mga bagong update sa isang application. Kung ang computer ay hindi nakakonekta sa network at walang IP address, bakit ito dapat gumana? Wala itong magagawa, kaya bakit iiwan ang isang programa na tumatakbo na walang ginagawa? Isipin ang Serbisyo sa Pamamahala ng Patakaran, na ginagamit kapag binabago ang Mga Patakaran ng Grupo o kapag ang isang computer ay sumali o umalis sa isang domain, ngunit ngayong nakakonekta na ang computer sa aking home network, ang serbisyo, muli, ay tumatakbo nang walang laman.

Ang paglitaw ng mga serbisyong nakabatay sa trigger

Ang solusyon sa mga problema sa itaas ay ilipat ang serbisyo mula sa "laging nasa estado" sa iba pang mga uri ng aktibidad sa background, tulad ng mga naka-iskedyul na gawain o na-trigger na mga serbisyo. Ang artikulong ito ay tungkol sa Windows 7 Trigger Start Services. Maraming mga kagiliw-giliw na bagay ang masasabi tungkol sa Windows 7 Scheduled Tasks, na gagawin sa mga susunod na artikulo.

Huling na-update: 10/31/2015

Ang isa sa pinakamahalagang bahagi ng Windows OS ay mga serbisyo. Sa katunayan, ito ay mga hiwalay na application na walang graphical na interface at nagsasagawa ng iba't ibang mga gawain sa background. Maaaring magsimula ang mga serbisyo kapag nagsimula ang operating system, o sa anumang oras na gumagana ang user. Ang isang karaniwang halimbawa ng mga serbisyo ay iba't ibang mga web server na nakikinig sa background sa isang partikular na port para sa mga koneksyon, at kung may mga koneksyon, nakikipag-ugnayan sila sa kanila. Maaari rin itong maging iba't ibang mga serbisyo sa pag-update ng auxiliary para sa iba pang mga naka-install na program na nakikipag-ugnayan sa server upang malaman kung mayroong bagong bersyon ng application. Sa pangkalahatan, maaari naming buksan ang panel ng mga serbisyo at makita para sa aming sarili ang lahat ng naka-install at tumatakbong mga serbisyo:

Tingnan natin kung paano lumikha ng iyong sariling mga serbisyo sa C#. Bilang ang gawain na ipapatupad, pipiliin naming subaybayan ang mga pagbabago sa isang partikular na folder sa file system. Ngayon, lumikha tayo ng isang serbisyo upang maisagawa ito.

Una, gumawa tayo ng bagong proyekto, na magiging uri ng Windows Service. Tawagan natin ang proyektong FileWatcherService:

Ang Visual Studio pagkatapos ay bumubuo ng isang proyekto na mayroong lahat ng kailangan mo. Bagama't hindi natin kailangang piliin ang partikular na uri ng proyektong ito, maaari tayong lumikha ng proyekto ng silid-aklatan ng klase at pagkatapos ay tukuyin ang lahat ng kinakailangang mga klase sa loob nito.

Kaya ganito ang hitsura ng bagong proyekto:

Mayroon ding isang file na Program.cs at mayroong aktwal na service node na Service1.cs.

Ang serbisyo ay kumakatawan sa isang normal na aplikasyon, ngunit hindi ito nagsisimula sa sarili nitong. Lahat ng mga tawag at access dito ay dumadaan sa service control manager (Service Control Manager o SCM). Kapag ang isang serbisyo ay awtomatikong nagsimula sa system startup o manu-mano, tinatawag ng SCM ang Main method sa klase ng Programa:

Static class Program ( static void Main() ( ServiceBase ServicesToRun; ServicesToRun = bagong ServiceBase ( new Service1() ); ServiceBase.Run(ServicesToRun); ) )

Ang pangunahing pamamaraan ay tinukoy bilang default upang magpatakbo ng maraming serbisyo nang sabay-sabay, na tinukoy sa hanay ng ServicesToRun. Gayunpaman, bilang default, ang proyekto ay naglalaman lamang ng isang serbisyo, Service1. Ang paglunsad mismo ay isinasagawa gamit ang Run method: ServiceBase.Run(ServicesToRun) .

Ang serbisyong sinisimulan ay kinakatawan ng Service1.cs node. Gayunpaman, ito ay hindi talaga isang simpleng code file. Kung bubuksan namin ang node na ito, makikita namin ang service designer file na Service1.Designer.cs at ang Service1 class.

Ang Service1 class ay aktwal na kumakatawan sa serbisyo. Bilang default, mayroon itong sumusunod na code:

Paggamit ng System; gamit ang System.Collections.Generic; gamit ang System.ComponentModel; gamit ang System.Data; gamit ang System.Diagnostics; gamit ang System.Linq; gamit ang System.ServiceProcess; gamit ang System.Text; gamit ang System.Threading.Tasks; namespace FileWatcherService ( public partial class Service1: ServiceBase ( public Service1() ( InitializeComponent(); ) protected override void OnStart(string args) ( ) protected override void OnStop() ( ) ) )

Ang klase ng serbisyo ay dapat magmana mula sa klase ng base ng ServiceBase. Tinutukoy ng klase na ito ang isang bilang ng mga pamamaraan, ang pinakamahalaga sa mga ito ay ang OnStart() na pamamaraan, na nagsisimula sa mga aksyon na ginagawa ng serbisyo, at ang OnStop() na pamamaraan, na humihinto sa serbisyo.

Pagkatapos tawagan ng SCM ang Main method at irehistro ang serbisyo, ito ay direktang tinatawag sa pamamagitan ng pagpapatakbo ng OnStart method.

Kapag nagpadala kami ng command upang ihinto ang isang serbisyo sa console ng mga serbisyo o sa pamamagitan ng command line, tinatawagan ng SCM ang paraan ng OnStop upang ihinto ito.

Bilang karagdagan sa dalawang pamamaraang ito sa klase ng serbisyo, maaari mong i-override ang ilang higit pang mga pamamaraan ng base class ng ServiceBase:

    OnPause: Tinatawag kapag naka-pause ang serbisyo

    OnContinue: Tinatawag kapag nagpatuloy ang isang serbisyo pagkatapos itong masuspinde

    OnShutdown: Tinatawag kapag nag-shut down ang Windows

    OnPowerEvent: Tinatawag kapag nagbago ang power mode

    OnCustomCommand: Tinatawag kapag nakatanggap ang isang serbisyo ng custom na command mula sa Service Control Manager (SCM)

Sa constructor ng Service1 class, ang InitializeComponent() na paraan ay tinatawag, na tinukoy sa designer file na Service1.Designer.cs:

Namespace FileWatcherService ( partial class Service1 ( private System.ComponentModel.IContainer components = null; protected override void Dispose(bool disposing) ( if (disposing && (components != null)) ( components.Dispose(); ) base.Dispose(disposing ); ) pribadong void InitializeComponent() ( mga bahagi = bagong System.ComponentModel.Container(); this.ServiceName = "Service1"; ) ) )

Ang tanging bagay na kailangang tandaan dito ay ang pagtatakda ng pangalan ng serbisyo (ServiceName property):

This.ServiceName = "Service1";

Ito ang pangalan na ipapakita sa console ng mga serbisyo pagkatapos i-install ang serbisyong ito. Maaari nating baguhin ito, o maaari nating iwanan ito kung ano ito.

Ngayon, baguhin natin ang code ng serbisyo tulad ng sumusunod:

Paggamit ng System; gamit ang System.ServiceProcess; gamit ang System.IO; gamit ang System.Threading; namespace FileWatcherService ( public partial class Service1: ServiceBase ( Logger logger; public Service1() ( InitializeComponent(); this.CanStop = true; this.CanPauseAndContinue = true; this.AutoLog = true; ) protected override void OnStart(string args) ( logger = new Logger(); Thread loggerThread = new Thread(new ThreadStart(logger.Start)); class Logger ( FileSystemWatcher watcher; object obj = new object(); bool enabled = true; public Logger() ( watcher = new FileSystemWatcher("D:\\Temp"); watcher.Deleted += Watcher_Deleted; watcher.Created + = Watcher_Created; watcher.Changed += Watcher.Renamed += Watcher_Renamed; ) public void Start() ( watcher.EnableRaisingEvents = true; while(enabled) ( Thread.Sleep(1000); ) ) public void Stop() ( watcher.EnableRaisingEvents = false; enabled = false; ) // pagpapalit ng pangalan ng mga file sa pribadong void Watcher_Renamed(object sender, RenamedEventArgs e) ( string fileEvent = "pinangalanan sa " + e.FullPath; string filePath = e.OldFullPath; RecordEntry(fileEvent, filePath); ) // change files private void Watcher_Changed(object sender, FileSystemEventArgs e) ( string fileEvent = "changed"; string filePath = e.FullPath; RecordEntry(fileEvent, filePath); ) // paggawa ng mga file private void Watcher_Created(object sender, FileSystemEventArgs e) ( string fileEvent = "nilikha"; string filePath = e.FullPath; RecordEntry(fileEvent, filePath); ) // pagtanggal ng mga file pribadong walang bisa Watcher_Deleted(tagapadala ng object, FileSystemEventArgs e) ( string fileEvent = "tinanggal"; string filePath = e.FullPath; RecordEntry(fileEvent, filePath); private void RecordEntry(string fileEvent, string filePath) ( lock (obj) ( gamit ang (StreamWriter writer = new StreamWriter("D:\\templog.txt", true)) ( writer .WriteLine(String.Format("(0) file (1) was (2)", DateTime.Now.ToString("dd/MM/yyyy hh:mm:ss"), filePath, fileEvent)); ;))))

Ang pangunahing klase na sumasaklaw sa lahat ng pag-andar ay ang klase ng Logger. Gamit ang object na FileSystemWatcher, susubaybayan nito ang mga pagbabago sa folder D://Temp. Tinutukoy ng Start() na paraan na babantayan namin ang mga pagbabago sa pamamagitan ng object na FileSystemWatcher. At ang lahat ng gawain ay magpapatuloy hangga't ang pinaganang boolean variable ay totoo . At ang Stop() na paraan ay magpapahintulot sa klase na wakasan.

Nagbibigay-daan sa iyo ang mga kaganapan sa FileSystemWatcher na subaybayan ang lahat ng mga pagbabago sa isang pinanood na folder. Ito ay magtatala ng mga pagbabago sa templog.txt file. Para maiwasan ang resource race para sa templog.txt file, kung saan naitala ang mga pagbabago, ang pamamaraan ng pagre-record ay hinarangan ng lock(obj) stub.

Bilang resulta, pagkatapos gumawa, baguhin, palitan ang pangalan at tanggalin, ang log file ay maglalaman ng tulad ng:

07/30/2015 12:15:40 file D:\Temp\New text document.txt ay ginawa 07/30/2015 12:15:46 file D:\Temp\New text document.txt ay pinalitan ng pangalan sa D:\ Temp\hello.txt 07/30/2015 12:15:55 file D:\Temp\hello.txt ay binago 07/30/2015 12:15:55 file D:\Temp\hello.txt ay binago 07/30 /2015 12:16:01 file D: Ang \Temp\hello.txt ay tinanggal

Sa Service1 service class mismo, ang ilang mga opsyon ay nakatakda sa constructor:

This.CanStop = true; // ang serbisyo ay maaaring ihinto ito.CanPauseAndContinue = true; // ang serbisyo ay maaaring i-pause at pagkatapos ay ipagpatuloy ito.AutoLog = true; // ang serbisyo ay maaaring sumulat sa log

Sa pamamaraang OnStart(), tinawag ang isang bagong thread upang simulan ang object ng Logger:

Protektadong override void OnStart(string args) ( logger = new Logger(); Thread loggerThread = new Thread(new ThreadStart(logger.Start)); loggerThread.Start(); )

Ang bagong thread ay kailangan dahil ang kasalukuyang thread ay nagpoproseso lamang ng mga SCM command at dapat na bumalik mula sa OnStart na paraan sa lalong madaling panahon.

Kapag natanggap ang isang utos mula sa SCM upang ihinto ang serbisyo, ang OnStop na paraan ay na-trigger, na tinatawag na logger.Stop() na paraan. Ang karagdagang pagkaantala ay magbibigay-daan sa logger thread na huminto:

Protektadong override void OnStop() ( logger.Stop(); Thread.Sleep(1000); )

Gayunpaman, ang klase ng serbisyo mismo ay hindi sapat. Kailangan din naming lumikha ng isang installer ng serbisyo.

O ang desktop ng mga user (parehong lokal at remote), gayunpaman, para sa ilang mga serbisyo ay posible ang isang pagbubukod - pakikipag-ugnayan sa console (session number 0, kung saan ang user ay lokal na nakarehistro o kapag sinimulan ang serbisyo mstsc gamit ang /console switch).

Mayroong ilang mga mode para sa mga serbisyo:

  • ipinagbabawal sa paglulunsad;
  • manu-manong pagsisimula (sa kahilingan);
  • awtomatikong pagsisimula kapag nag-boot ang computer;
  • awtomatikong (naantala) paglulunsad (ipinakilala sa Windows Vista at Windows Server 2008);
  • mandatoryong serbisyo/driver (awtomatikong pagsisimula at kawalan ng kakayahan (para sa user) na ihinto ang serbisyo).

Background mode

Magsimula, huminto, at baguhin ang mga serbisyo ng Windows

Ang mga serbisyo at ang kanilang mga katangian ay maaaring baguhin sa MMC:

Maaaring may ilang serbisyo ang iba't ibang bersyon ng mga operating system at hindi ang iba. Ang ilang mga application at program na naka-install nang hiwalay ay maaari ding lumikha ng sarili nilang mga serbisyo.

Listahan ng mga serbisyo ng operating system ng Microsoft Windows

Display name Pangalan ng serbisyo Mga pag-andar Paglalarawan
DHCP client Dhcp Nagrerehistro at nag-a-update ng mga IP address at DNS record para sa computer na ito. Kung ang serbisyong ito ay itinigil, ang computer na ito ay hindi makakakuha ng mga dynamic na IP address at magsagawa ng mga DNS update.
DNS client Dnscache Ini-cache ng DNS Client service (dnscache) ang mga pangalan ng Domain Name System (DNS) at nirerehistro ang ganap na kwalipikadong pangalan ng isang ibinigay na computer. Kung ang serbisyo ay itinigil, ang DNS name resolution ay magpapatuloy. Gayunpaman, ang mga resulta ng DNS name queues ay hindi mai-cache at ang pangalan ng computer ay hindi mairerehistro.
KtmRm para sa distributed transaction coordinator KtmRm Nag-coordinate ng mga transaksyon sa pagitan ng MSDTC at ng Kernel Transaction Manager (KTM).
ReadyBoost EMDMgmt ReadyBoost Suporta para sa pagpapabuti ng pagganap ng system gamit ang teknolohiyang ReadyBoost.
Superfetch SysMain Superfetch Pinapanatili at pinapabuti ang pagganap ng system.
Windows Audio Audiosrv Pamamahala ng mga tool sa audio para sa mga programa sa Windows. Kung ihihinto ang serbisyong ito, hindi gagana nang tama ang mga audio device at effect.
Windows CardSpace idsvc Nagbibigay ng secure na kakayahang gumawa, pamahalaan, at ilantad ang mga digital na pagkakakilanlan.
Awtomatikong pag-update WUAUSERV Kasama ang pag-download at pag-install ng mga update sa Windows. Kung hindi pinagana ang serbisyo, hindi magagamit ng computer na ito ang Mga Awtomatikong Update o ang Web site ng Windows Update.
Remote Procedure Call (RPC) RpcSs Nagbibigay ng pagmamapa sa pagitan ng mga endpoint at iba pang mga serbisyo ng RPC.

Listahan ng mga serbisyong ginawa ng mga application at program ng Microsoft

Mga halimbawa ng mga serbisyong ginawa ng mga third-party na application at program

Display name Pangalan ng serbisyo Mga pag-andar Paglalarawan
ESET HTTP Server EhttpSrv proteksyon ng antivirus Bahagi ng ESET HTTP Server

Paano magpatakbo ng isang application bilang isang serbisyo ng Windows

Posible bang magpatakbo ng isang application ng kliyente bilang isang serbisyo? Sa isa sa mga ito, inilarawan ko ang mga paraan upang lumikha ng isang serbisyo sa Windows gamit ang mga karaniwang tool sa OS. Gayunpaman, hindi lahat ng console application ay maaaring tumakbo bilang isang serbisyo, at ang mga program na may isang graphical na interface, sa prinsipyo, ay hindi maaaring gumana sa ganitong paraan. Ngunit posible pa ring patakbuhin ang application bilang isang serbisyo, at ang isang programa na may orihinal na pangalan ay makakatulong sa amin dito Tagapamahala ng Serbisyong Walang Pagsipsip.

Ang NSSM ay libre at open source na software at sinusuportahan ang lahat ng mga operating system ng Microsoft mula sa Windows 2000 hanggang Windows 8. Ang NSSM ay hindi nangangailangan ng pag-install, i-download lamang at i-unzip ito. Kasama sa pamamahagi ang mga bersyon para sa 32- at 64-bit na operating system. Maaari mong makuha ang programa mula sa website na nssm.cc, sa ngayon ang pinakabagong stable na bersyon ay 2.21.1, na gagamitin ko.

Upang ipakita ang mga kakayahan ng NSSM, subukan nating patakbuhin ang Windows Notepad bilang isang serbisyo sa Windows 8.1.

Paglikha ng Serbisyo

Upang lumikha ng isang serbisyo na pinangalanan notepad ilunsad ang command console, pumunta sa folder na may naka-unpack na NSSM (para sa 64-bit na Windows) at ipasok ang command na nssm install notepad, na magbubukas sa NSSM graphical installer window. Upang lumikha ng isang serbisyo, tukuyin lamang ang path sa executable na file sa field ng Path at i-click ang button na "I-install ang serbisyo". Bukod pa rito, sa field na Mga Opsyon maaari mong tukuyin ang mga susi na kinakailangan upang simulan ang serbisyo.

Maaari mo ring tukuyin ang ilang karagdagang parameter kapag gumagawa ng bagong serbisyo.

Inililista ng tab na Pag-shutdown ang mga paraan ng pag-shutdown at mga timeout na ginagamit kapag normal na nag-shut down o nag-crash ang application. Kapag nakatanggap ang NSSM ng stop command (halimbawa, kapag ang isang application ay isinara), sinusubukan nitong ihinto ang kinokontrol na application sa isang normal na paraan. Kung hindi tumugon ang aplikasyon, maaaring puwersahang wakasan ng NSSM ang lahat ng proseso at subprocess ng application na ito.

Mayroong apat na hakbang sa pag-shut down ng application, at bilang default, gagamitin ang mga ito sa ganitong pagkakasunud-sunod:

Sa unang yugto, sinusubukan ng NSSM na bumuo at magpadala ng isang kaganapan Ctrl+C. Gumagana nang maayos ang paraang ito para sa mga console application o script, ngunit hindi naaangkop para sa mga graphical na application;
Pagkatapos ay nakita ng NSSM ang lahat ng mga window na nilikha ng application at nagpapadala sa kanila ng WM_CLOSE na mensahe, na nagiging sanhi ng pag-alis ng application;
Ang ikatlong hakbang ay kinakalkula ng NSSM ang lahat ng mga thread na nilikha ng application at nagpapadala sa kanila ng isang WM_QUIT na mensahe, na matatanggap kung ang application ay may thread message queue;
Bilang huling paraan, maaaring tawagan ng NSSM ang paraan ng TerminateProcess(), na pinipilit na wakasan ang aplikasyon.

Posibleng hindi paganahin ang ilan o kahit na ang lahat ng mga pamamaraan, ngunit gumagana ang iba't ibang mga pamamaraan para sa iba't ibang mga application at inirerekomenda na iwanan ang lahat ng bagay upang matiyak na ang application ay nagsasara nang tama.

Bilang default, kapag nag-crash ang isang serbisyo, sinusubukan ng NSSM na i-restart ito. Sa tab na "Lumabas sa mga pagkilos," maaari mong baguhin ang awtomatikong pagkilos kapag hindi normal na natapos ang application, pati na rin magtakda ng pagkaantala bago awtomatikong mag-restart ang application.

Sa tab na "Input/Output (I/O)", maaari mong itakda ang pag-redirect ng input/output ng application sa isang tinukoy na file.

Sa tab na "Environment," maaari kang magtakda ng mga bagong variable ng environment para sa serbisyo, o i-override ang mga umiiral na.

Hindi mo rin magagamit ang graphical na shell at agad na lumikha ng isang serbisyo sa console gamit ang sumusunod na command:

nssm install notepad ″C:\Windows\system32\notepad.exe″

Pamamahala ng serbisyo

Pagkatapos gawin ang serbisyo gamit ang NSSM, pumunta sa snap-in ng Mga Serbisyo at hanapin ang serbisyo ng notepad. Tulad ng nakikita mo, sa hitsura ay hindi ito naiiba sa iba pang mga serbisyo; Gayunpaman, tandaan na ang nssm.exe ay nakalista bilang executable file.

At kung pupunta tayo sa Task Manager, makikita natin ang sumusunod na larawan: Ang NSSM ay tumatakbo bilang pangunahing (magulang) na proseso, ang serbisyo ng notepad ay tumatakbo bilang proseso ng bata nito, at ang application na Notepad ay tumatakbo na sa prosesong ito ng bata.

Pag-alis ng isang serbisyo

Upang alisin ang isang serbisyo, ilagay ang nssm remove notepad command at kumpirmahin ang pag-alis nito. At sa pamamagitan ng pagpasok ng command nssm remove notepad confirm , magagawa mo nang walang kumpirmasyon.

Magsimula ng serbisyo nang interactive

Ang pangunahing pagkakaiba sa pagitan ng isang application ng user at isang serbisyo ay na, sa sandaling inilunsad, ang application ay maaaring mangailangan ng karagdagang mga aksyon ng user upang magpatuloy sa pagtakbo, tulad ng pagpindot sa isang pindutan o pagpasok ng isang command. Upang gawin ito, kailangan mong makakuha ng access dito, na, bilang ito ay lumiliko, ay hindi napakadaling gawin.

Upang makapagsimula ng serbisyo sa interactive na mode, kailangan mong buksan ang mga katangian nito sa snap-in ng Mga Serbisyo at sa tab na "Login", lagyan ng check ang checkbox na "Pahintulutan ang pakikipag-ugnayan sa desktop."

At pagkatapos ay magsisimula ang mga himala :) Isang serbisyo na inilunsad sa interactive na mode ay bubukas sa isang nakahiwalay na session (session 0). Maa-access lang ang session na ito sa pamamagitan ng paggamit ng Interactive Services Detection Service (ui0detect), na sinusubaybayan ang startup ng mga interactive na serbisyo sa computer at nagbibigay ng alerto. Sa Windows 7\Server 2008 ang serbisyong ito ay aktibo bilang default, ngunit sa Windows 8\Server 2012 ito ay hindi pinagana at hindi lilitaw sa graphical snap-in ng Mga Serbisyo (kahit hindi ko nakita ito doon). Bukod dito, kung nahanap mo ang mahiwagang serbisyong ito at subukang simulan ito, makakatanggap ka ng mensahe ng error.

Ngunit ang katotohanan ay upang patakbuhin ito, dapat mong payagan ang mga interactive na serbisyo na tumakbo sa iyong computer. Samakatuwid, buksan ang registry editor, hanapin sa seksyong HKLM\System\CurrentControlSet\Control\Windows ang isang parameter ng uri ng DWORD na pinangalanan NoInteractiveServices at itakda ang halaga nito sa 0 .

Pagkatapos ay buksan ang PowerShell console at simulan ang serbisyo ng pagtuklas gamit ang command:

Start-Service -Name ui0detect

Pagkatapos matiyak na gumagana ang serbisyo ng pagtuklas, i-restart namin ang serbisyo ng notepad, at makuha namin ang window na ito. Piliin ang "Tingnan ang mensahe"

at nakita namin ang aming sarili sa null session kung saan tumatakbo ang aming application. Pagkatapos ay ginagawa namin ang mga kinakailangang aksyon kasama nito at bumalik.

Ito ay isang kawili-wiling solusyon para sa pagpapatakbo ng mga application bilang mga serbisyo ng Windows. Hindi ang pinaka maganda, ngunit medyo pare-pareho sa pangalan nito :)


Ang serbisyo ng Windows NT ay isang espesyal na proseso na may pinag-isang interface para sa pakikipag-ugnayan sa operating system ng Windows NT. Ang mga serbisyo ay nahahati sa dalawang uri - mga serbisyo ng Win32, na nakikipag-ugnayan sa operating system sa pamamagitan ng Service Control Manager (SCM), at mga driver, na nagpapatakbo gamit ang Windows NT device driver protocol. Tatalakayin lamang namin ang mga serbisyo ng Win32 sa ibang pagkakataon sa artikulong ito.

Aplikasyon ng mga serbisyo

Ang isa sa pinakamahalagang katangian ng serbisyo ay hindi interaktibidad. Ang isang karaniwang serbisyo ay tumatakbo sa background na hindi napapansin ng karaniwang gumagamit. Dahil dito, ang mga serbisyo ay pinakaangkop para sa pagpapatupad ng mga sumusunod na uri ng mga aplikasyon:

  • Mga server sa arkitektura ng client-server (halimbawa, MS SQL, MS Exchange Server)
  • Mga serbisyo sa network Windows NT (Server, Workstation);
  • Server (sa mga tuntunin ng pag-andar) mga bahagi ng mga ipinamahagi na application (halimbawa, lahat ng uri ng mga programa sa pagsubaybay).

Mga pangunahing katangian ng mga serbisyo

Ang serbisyo ay nakikilala mula sa isang regular na application ng Win32 sa pamamagitan ng 3 pangunahing katangian. Tingnan natin ang bawat isa sa kanila.

Una, posibleng ihinto nang tama (suspinde) ang serbisyo. Ang isang user o iba pang application na gumagamit ng mga karaniwang mekanismo ay may kakayahang baguhin ang estado ng isang serbisyo - ilipat ito mula sa isang tumatakbong estado patungo sa isang naka-pause na estado, o kahit na ihinto ito sa pagtakbo. Sa kasong ito, bago baguhin ang estado nito, ang serbisyo ay tumatanggap ng isang espesyal na abiso, salamat sa kung saan maaari itong magsagawa ng mga aksyon na kinakailangan upang lumipat sa isang bagong estado, halimbawa, ilabas ang mga nasasakupang mapagkukunan.

Pangalawa, ang kakayahang simulan ang serbisyo bago irehistro ang gumagamit at, bilang isang resulta, ang kakayahang magtrabaho nang walang rehistradong gumagamit. Anumang serbisyo ay maaaring awtomatikong magsimula kapag ang operating system ay nagsimula at nagsimulang gumana kahit na bago mag-log in ang user sa system.

At sa wakas, ang kakayahang magtrabaho sa isang arbitrary na konteksto ng seguridad. Ang konteksto ng seguridad ng Windows NT ay tumutukoy sa isang hanay ng mga karapatan sa pag-access para sa isang proseso sa iba't ibang mga object at data ng system. Hindi tulad ng karaniwang application ng Win32, na palaging tumatakbo sa konteksto ng seguridad ng user na kasalukuyang naka-log on sa system, para sa isang serbisyo ang konteksto ng seguridad ng pagpapatupad nito ay maaaring matukoy nang maaga. Nangangahulugan ito na ang isang serbisyo ay maaaring magkaroon ng hanay ng mga karapatan sa pag-access sa mga object ng system na tinukoy nang maaga at sa gayon ay nililimitahan ang saklaw ng mga aktibidad nito. Para sa mga serbisyo, mayroong isang espesyal na uri ng default na konteksto ng seguridad na tinatawag na Local System. Ang isang serbisyong tumatakbo sa kontekstong ito ay may mga karapatan lamang sa mga mapagkukunan sa lokal na computer. Walang mga pagpapatakbo ng network ang maaaring gawin gamit ang mga karapatan ng Local System, dahil ang kontekstong ito ay may katuturan lamang sa lokal na computer at hindi kinikilala ng ibang mga computer sa network.

Pakikipag-ugnayan ng serbisyo sa iba pang mga application

Anumang application na may naaangkop na mga karapatan ay maaaring makipag-ugnayan sa serbisyo. Ang pakikipag-ugnayan, una sa lahat, ay nagsasangkot ng pagbabago sa estado ng serbisyo, iyon ay, paglilipat nito sa isa sa tatlong estado - tumatakbo (Start), sinuspinde (I-pause), huminto, at isinasagawa sa pamamagitan ng pagsusumite ng mga kahilingan sa SCM. Ang mga kahilingan ay may tatlong uri - mga mensahe mula sa mga serbisyo (pag-aayos ng kanilang mga estado), mga kahilingang nauugnay sa pagbabago ng pagsasaayos ng isang serbisyo o pagkuha ng impormasyon tungkol dito, at mga kahilingan ng application na baguhin ang estado ng isang serbisyo.

Upang pamahalaan ang isang serbisyo, kailangan mo munang makuha ang hawakan nito gamit ang OpenService Win32 API function. Ang StartService function ay magsisimula ng isang serbisyo. Kung kinakailangan, ang estado ng serbisyo ay binago sa pamamagitan ng pagtawag sa ControlService function.

Database ng Serbisyo

Ang impormasyon tungkol sa bawat serbisyo ay naka-imbak sa registry - sa key na HKLM\SYSTEM\CurrentControlSet\Services\ServiceName. Naglalaman ito ng sumusunod na impormasyon:

  • Uri ng serbisyo. Isinasaad kung ang application na ito ay nagpapatupad lamang ng isang serbisyo (eksklusibo) o kung mayroong ilan sa mga ito sa application. Ang isang eksklusibong serbisyo ay maaaring gumana sa anumang konteksto ng seguridad. Ang maramihang mga serbisyo sa loob ng parehong application ay maaari lamang tumakbo sa konteksto ng LocalSystem.
  • Uri ng paglulunsad. Awtomatiko - magsisimula ang serbisyo sa pagsisimula ng system. On demand - ang serbisyo ay sinimulan nang manu-mano ng user. Na-deactivate - Hindi masisimulan ang serbisyo.
  • Ang pangalan ng executable module (EXE file).
  • Startup order kaugnay ng iba pang serbisyo. Sa ilang mga kaso, para gumana nang tama ang isang serbisyo, dapat na tumatakbo ang isa o higit pang mga serbisyo. Sa kasong ito, ang pagpapatala ay naglalaman ng impormasyon tungkol sa mga serbisyo na nagsimula bago ang isang ito.
  • Ang konteksto ng seguridad ng pagpapatupad ng serbisyo (pangalan ng network at password). Bilang default, ang konteksto ng seguridad ay LocalSystem.

Ang mga application na gustong kumuha ng impormasyon tungkol sa isang serbisyo o baguhin ang isang setting ng serbisyo ay dapat na mahalagang baguhin ang impormasyon sa database ng serbisyo sa registry. Magagawa ito gamit ang kaukulang mga function ng Win32 API:

  • OpenSCManager, CreateService, OpenService, CloseServiceHandle - upang lumikha (magbukas) ng isang serbisyo;
  • QueryServiceConfig, QueryServiceObjectSecurity, EnumDependentServices, EnumServicesStatus - upang makakuha ng impormasyon tungkol sa serbisyo;
  • ChangeServiceConfig, SetServiceObjectSecurity, LockServiceDatabase, UnlockServiceDatabase, QueryServiceLockStatus - upang baguhin ang impormasyon ng configuration ng serbisyo.

Panloob na istraktura ng serbisyo.

Upang mangyari ito, ang application ay dapat na nakaayos nang naaayon, ibig sabihin, isama ang isang tiyak na hanay ng mga function (sa mga termino ng C++) na may isang tiyak na pag-andar. Tingnan natin nang maikli ang bawat isa sa kanila.

pangunahing tungkulin

Tulad ng alam mo, ang pangunahing function ay ang entry point ng anumang Win32 console application. Kapag nagsimula ang serbisyo, ang code para sa function na ito ay magsisimulang mag-execute muna. Sa loob ng 30 segundo mula sa simula, dapat na tawagan ng pangunahing function ang StartServiceCtrlDispatcher upang magtatag ng koneksyon sa pagitan ng application at ng SCM. Ang lahat ng komunikasyon sa pagitan ng anumang serbisyo sa isang partikular na application at ang SCM ay isinasagawa sa loob ng StartServiceCtrlDispatcher function, na magwawakas lamang pagkatapos na huminto ang lahat ng mga serbisyo sa application.

SerbisyoMain function

Bilang karagdagan sa entry point sa buong proseso, mayroon ding hiwalay na entry point para sa bawat isa sa mga serbisyong ipinatupad sa application. Ang mga pangalan ng mga function na mga service entry point (para sa pagiging simple, tawagan natin silang lahat ng pareho - ServiceMain) ay ipinapasa sa SCM sa isa sa mga parameter kapag tumatawag sa StartServiceCtrlDispatcher. Kapag nagsimula ang bawat serbisyo, isang hiwalay na thread ang gagawin upang maisagawa ang ServiceMain.

Sa pagkakaroon ng natanggap na kontrol, ang ServiceMain ay dapat munang magparehistro ng isang service request handler, ang Handler function, para sa bawat serbisyo sa application. Karaniwan itong sinusundan sa ServiceMain ng ilang mga aksyon upang simulan ang serbisyo - paglalaan ng memorya, pagbabasa ng data, atbp. Ang mga pagkilos na ito ay dapat na sinamahan ng mga abiso ng SCM na ang serbisyo ay nasa proseso pa rin ng pagsisimula at walang mga pagkabigo na naganap. Ipinapadala ang mga notification gamit ang mga tawag sa function na SetServiceStatus. Ang lahat ng mga tawag maliban sa pinakahuli ay dapat na may parameter na SERVICE_START_PENDING, at ang pinakabago ay dapat na may parameter na SERVICE_RUNNING. Ang dalas ng mga tawag ay tinutukoy ng developer ng serbisyo batay sa sumusunod na kundisyon: ang tagal ng agwat ng oras sa pagitan ng dalawang katabing SetServiceStatus na mga tawag ay hindi dapat lumampas sa halaga ng dwWaitHint parameter na ipinasa sa SCM sa una sa dalawang tawag. Kung hindi, ang SCM, na hindi nakatanggap ng susunod na abiso sa oras, ay pilit na ihihinto ang serbisyo. Ang pamamaraang ito ay nagpapahintulot sa iyo na maiwasan ang sitwasyon ng serbisyo sa simula bilang isang resulta ng paglitaw ng ilang mga pagkabigo (tandaan na ang mga serbisyo ay karaniwang hindi interactive at maaaring magsimula sa kawalan ng user). Ang karaniwang kasanayan ay pagkatapos makumpleto ang susunod na hakbang sa pagsisimula, aabisuhan ang SCM.

Pag-andar ng handler

Gaya ng nabanggit sa itaas, ang Handler ay isang prototype ng isang callback function, isang service request handler, natatangi para sa bawat serbisyo sa application. Tinatawag ang Handler kapag nakatanggap ang serbisyo ng kahilingan (simula, i-pause, ipagpatuloy, ihinto, kasalukuyang mensahe ng estado) at isagawa ang mga kinakailangang aksyon alinsunod sa kahilingan, pagkatapos nito ay iuulat ang bagong estado sa SCM.

Dapat bigyang pansin ang isang kahilingan - ang kahilingang natanggap kapag isinara ang system (Shutdown). Ang kahilingang ito ay nagpapahiwatig ng pangangailangang mag-deinitialize at lumabas. Sinabi ng Microsoft na ang bawat serbisyo ay binibigyan ng 20 segundo upang isara bago sapilitang huminto. Gayunpaman, ipinakita ng mga pagsusuri na ang kundisyong ito ay hindi palaging natutugunan at ang serbisyo ay napipilitang huminto bago mag-expire ang panahong ito.

Sistema ng seguridad ng serbisyo

Ang anumang aksyon sa mga serbisyo ay nangangailangan ng aplikasyon na magkaroon ng mga naaangkop na karapatan. Ang lahat ng mga application ay may mga karapatan na kumonekta sa SCM, magbilang ng mga serbisyo, at suriin kung ang database ng serbisyo ay naharang. Tanging ang mga application na may mga karapatang pang-administratibo ang maaaring magrehistro ng bagong serbisyo sa system o i-block ang database ng serbisyo.

Ang bawat serbisyo ay may deskriptor ng seguridad na naglalarawan kung sinong mga user ang may karapatan sa kung aling operasyon. Default:

  • Ang lahat ng mga user ay may mga karapatan sa SERVICE_QUERY_CONFIG, SERVICE_QUERY_STATUS, SERVICE_ENUMERATE_DEPENDENTS, SERVICE_INTERROGATE, at SERVICE_USER_DEFINED_CONTROL;
  • Ang mga user na kabilang sa pangkat ng Power Users at ang LocalSystem account ay mayroon ding mga karapatan sa SERVICE_START, SERVICE_PAUSE_CONTINUE at SERVICE_STOP;
  • Ang mga user na kabilang sa mga pangkat ng Administrators at System Operators ay may karapatan sa SERVICE_ALL_ACCESS.

Mga serbisyo at interaktibidad

Bilang default, maaari lamang tumakbo ang mga interactive na serbisyo sa konteksto ng seguridad ng LocalSystem. Ito ay dahil sa mga kakaibang katangian ng pagpapakita sa screen ng monitor sa Windows NT, kung saan mayroong, halimbawa, isang bagay tulad ng "Desktop", upang gumana kung saan kailangan mong magkaroon ng naaangkop na mga karapatan sa pag-access, na isang arbitrary na account maliban sa LocalSystem maaaring wala. Sa kabila ng katotohanan na sa karamihan ng mga kaso ang limitasyong ito ay hindi makabuluhan, kung minsan ay kailangang lumikha ng isang serbisyo na magpapakita ng impormasyon sa screen ng monitor at sa parehong oras ay isasagawa sa isang konteksto ng seguridad maliban sa LocalSystem, para sa halimbawa, isang bahagi ng application server para sa pagpapatakbo ng mga application sa isang malayuang computer.

Code snippet mula sa . inilalarawan ang posibilidad na ito.

Sa fragment na ito, bilang tugon sa isang kahilingan na ipinadala ng client side ng application bilang isang resulta ng RPC, ang serbisyo ay nagpapakita ng isang text message sa screen ng monitor.

Halimbawang Serbisyo (Mga Key Snippet)

Tingnan natin ang halimbawa ng mga pangunahing fragment ng isang application sa C++ na nagpapatupad ng serbisyo ng Windows NT. Para sa kalinawan, ang mga hindi mahalagang bahagi ng code ay tinanggal.

pangunahing tungkulin

Ang pangunahing function code ay ipinapakita sa B.

SerbisyoMain function

Ang isang tampok ng code na nilalaman sa ServiceMain ay madalas na imposibleng mahulaan nang maaga ang oras ng pagpapatupad ng isang partikular na operasyon, lalo na kung isasaalang-alang na ang pagpapatupad nito ay nangyayari sa isang operating system na may preemptive multitasking. Kung ang operasyon ay mas matagal kaysa sa agwat ng oras na tinukoy sa SetServiceStatus na parameter ng tawag, hindi maipapadala ng serbisyo ang susunod na abiso sa oras, na nagiging sanhi ng paghinto ng SCM sa operasyon nito. Kasama sa mga halimbawa ng mga potensyal na operasyon ang mga tawag sa mga function ng networking na may malalaking timeout o sabay-sabay na pagbabasa ng malaking halaga ng impormasyon mula sa mabagal na medium. Bilang karagdagan, ang diskarte na ito ay ganap na hindi naaangkop kapag nagde-debug ng isang serbisyo, dahil ang pagpapatupad ng programa sa debugger ay sinamahan ng mahabang pag-pause, na kinakailangan para sa developer.

Upang malampasan ang problemang ito, ang lahat ng mga operasyon na nakikipag-ugnayan sa SCM ay dapat na isagawa sa isang hiwalay na thread, na independiyente sa mga aksyon na nagaganap sa yugto ng pagsisimula.

Nagpapakita ang B ng isang algorithm para sa wastong pagsisimula ng isang serbisyo gamit ang isang auxiliary thread.

Pag-andar ng handler

Ipinapakita ng B ang code para sa function ng Handler at mga auxiliary thread. Para sa mga kahilingang "Stop" at "Shutdown," ginagamit ang isang algorithm para sa wastong paghinto ng serbisyo, katulad ng ginamit kapag nagsisimula ng isang serbisyo, na may pagkakaiba lamang na sa halip na ang SERVICE_START_PENDING parameter, ang SERVICE_STOP_PENDING parameter ay ipinapasa sa SetserviceStatus, at sa halip ng SERVICE_RUNNING - SERVICE_STOPPED.

Sa isip, ang mga kahilingang "I-pause" at "Magpatuloy" ay dapat ding gumamit ng diskarteng ito. Ang isang matanong na mambabasa ay madaling ipatupad ito batay sa mga halimbawang ito.

Konklusyon

Sa konklusyon, nais naming tandaan na ang pagbuo ng mga serbisyo ay hindi nagbago sa paglipat sa Windows NT 2000. Ang mga serbisyo ay patuloy na isang mahalagang bahagi ng software sa Windows platform, na nagbibigay sa mga developer ng malawak na hanay ng mga opsyon.


// Function na katulad ng MessageBox Win32 API int ServerMessageBox(RPC_BINDING_HANDLE h, LPSTR lpszText, LPSTR lpszTitle, UINT fuStyle) ( DWORD dwThreadId; HWINSTA hwinstaSave; HDESK hdeskSave; HWINSTA hwinstadeskUser; // Alalahanin ang kasalukuyang object; "HWINSTA hwinstadeskUser;" istasyon " at "Desktop". GetDesktopWindow(); hwinstaSave = GetProcessWindowStation(); dwThreadId = GetCurrentThreadId(); hdeskSave = GetThreadDesktop(dwThreadId); // Baguhin ang konteksto ng seguridad sa isang // na ang tumatawag na RPC client ay // at makakuha ng access sa user // objects "Window station" at "Desktop". RpcImpersonateClient(h); SetProcessWindowStation( hwinstaUser); hdeskUser = OpenDesktop("Default", 0, FALSE, MAXIMUM_ALLOWED(); RpcRevertToSelf(); ) SetThreadDesktop(hdeskUser); // Magpakita ng regular na text window. resulta = MessageBox(NULL, lpszText, lpszTitle, fuStyle); // Ibalik ang mga na-save na bagay // "Window station" at "Desktop". SetThreadDesktop(hdeskSave); SetProcessWindowStation(hwinstaSave); CloseDesktop(hdeskUser); CloseWindowStation(hwinstaUser); ibalik ang resulta; ) void main() ( SERVICE_TABLE_ENTRY steTable = ( (SERVICENAME, ServiceMain), (NULL, NULL) ); // Magtatag ng koneksyon sa SCM. Sa loob ng function na ito // tinatanggap at ipinapadala ang mga kahilingan. StartServiceCtrlDispatcher(steTable); ) void WINAPI ServiceMain (DWORD dwArgc, LPSTR *psArgv) ( // Irehistro kaagad ang tagapangasiwa ng kahilingan. hSS = RegisterServiceCtrlHandler(SERVICENAME, ServiceHandler); sStatus.dwCheckPoint = 0; sStatus.dwControlsAccepted = SERVICE_ACCEPT_STOPAC = us.dwServiceType = SERVICE_WIN32_OWN_PROCESS ; sStatus.dwWaitHint = 0; sStatus.dwWin32ExitCode = NOERROR; bawat // segundo. , na ang serbisyo ay nasa proseso ng pagsisimula ng // Ang isang kaganapan ay nilikha upang i-synchronize ang thread. hSendStartPending = CreateEvent(NULL, TRUE, FALSE, NULL); HANDLE hSendStartThread; DWORD dwThreadId; hSendStartThread = CreateThread(NULL, 0, SendStartPending, NULL, 0, &dwThreadId); //Ang lahat ng pagsisimula ng serbisyo ay ginagawa dito. InitService(); SetEvent(hSendStartPending); if(WaitForSingleObject(hSendStartThread, 2000) != WAIT_OBJECT_0) ( TerminateThread(hSendStartThread, 0); ) CloseHandle(hSendStartPending); CloseHandle(hSendStartThread); hWork = CreateEvent(NULL, TRUE, FALSE, NULL); hServiceThread = CreateThread(NULL, 0, ServiceFunc, 0, 0, &dwThreadId); sStatus.dwCurrentState = SERVICE_RUNNING; SetServiceStatus(hSS, &sStatus); ) // Isang function ng thread na nagpapadala ng mga notification sa SCM // bawat segundo na ang proseso ng pagsisimula ay isinasagawa. Ang function // ay nagtatapos kapag ang hSendStartPending // na kaganapan ay nakatakda. DWORD WINAPI SendStartPending(LPVOID) ( sStatus.dwCheckPoint = 0; sStatus.dwCurrentState = SERVICE_START_PENDING; sStatus.dwWaitHint = 2000; // “Sleep” para sa 1 segundo. Kung pagkatapos ng 1 segundo // ang hSend ay hindi pa Nagsisimula ang signal estado ( ang pagsisimula ng serbisyo ay hindi // natapos), ipadala ang susunod na abiso, // pagtatakda ng maximum na agwat ng oras // sa 2 segundo, upang mayroong isang margin ng oras hanggang // sa susunod na abiso habang (totoo) ( ​​SetServiceStatus(hSS, &sStatus); sStatus.dwCheckPoint++; Pagbabasa ng data, // paglalaan ng memorya, atbp. void InitService() ( ... ) // Function na naglalaman ng service code. DWORD WINAPI ServiceFunc(LPVOID) ( while (true) ( ​​​​if (!bPause) ( // Naglalaman ito ng code na karaniwang // nagsasagawa ng ilang uri ng cyclic operations... ) if (WaitForSingleObject(hWork, 1000)!=WAIT_TIMEOUT ) break; ) return 0; ) // Humiling ng handler mula sa SCM void WINAPI ServiceHandler(DWORD dwCode) ( switch (dwCode) ( case SERVICE_CONTROL_STOP: case SERVICE_CONTROL_SHUTDOWN: ReportStatusToSCMgr(SERVICE_STOP_PENDING,0,Pending , 0_ERRSTOP, NO_ERROR = 0. TRUE, FALSE, NULL); hSendStopThread = CreateThread(NULL, 0, SendStopPending, NULL, 0, & dwThreadId); ; CloseHandle(hServiceThread); kung(WaitForSingleObject(hSendStopThread, 2000) != WAIT_OBJECT_0) ( TerminateThread(hSendStopThread, 0); ) CloseHandle(hSendStopPending;SetService(hSService); pahinga; DWORD WINAPI SendStopPending(LPVOID) ( sStatus.dwCheckPoint = 0; sStatus.dwCurrentState = SERVICE_STOP_PENDING; sStatus.dwWaitHint = 2000; while (true) ( ​​​​SetServiceStatus(hSSs, &stusStatus.s); endStopPending, 1000 ) =WAIT_TIMEOUT) sStatus.dwCheckPoint = 0;