[ Nedeljko @ 15.09.2009. 12:44 ] @
Koristim MinGW C++ prevodilac. Treba da napisem windows servis.

Poenta je kako da kada startujem proces, recimo iy komandne linije, da on nastavi da radi i nakon sto se ugasi cmd.

Pod Linux-om je lako: if (fork()) return 0;

Kako pod Windows-om? Ima li neko link na neki sablon za pravljenje servisa?
[ Mihajlo Cvetanović @ 15.09.2009. 13:18 ] @
Pa ako se niko ne javi, uvek je tu Gugl. Ovo recimo deluje obećavajuće: http://msdn.microsoft.com/en-us/library/ms810429.aspx

U Windowsu servis mora da se registruje (preko API-ja). To se obično radi tako što pokreneš sam exe sa -I svičem, a unutar exe-a se na to pozove API koji registruje sam exe.
[ X Files @ 15.09.2009. 19:26 ] @
Nikada nisam radio Windows service aplikaciju pod MinGW-om.

Pronasao sam ovo, mozda pomogne:
http://forums.codeblocks.org/index.php?topic=7196.msg55012


Ipak, posto znam da povremeno koristis i besplatan Turbo C++, mozda se odlucis i za neku takvu varijantu. Ovde ima primer koji radi:
http://www.elitesecurity.org/p1525450
(kod je za BCB6, ali treba da je kompatibilno sa Turbo C++)
[ Nedeljko @ 15.09.2009. 20:40 ] @
Lepo. lepo, ali zašto prilagođen program iz priloga ne radi? Ili ja ne umem da pokrenem servis pod Windows-om. Napominjem da mi je ovo prvo iskustvo te vrste pod Windows-ima. Izbacuje grešku "StartServiceCtrlDispatcher failed".
[ Mihajlo Cvetanović @ 15.09.2009. 21:49 ] @
Ovako na prvi pogled vidim da je u DispatchTable tabeli data funkcija kastovana u ono što se očekuje. Kastovanje funkcije je skoro uvek pogrešno. Ako je suditi po MSDN-u funkcija InitService ovde mora da ima sledeći potpis:

VOID WINAPI InitService(DWORD dwArgc, LPTSTR *lpszArgv);
[ deerbeer @ 16.09.2009. 09:04 ] @
Citat:
Nedeljko: Lepo. lepo, ali zašto prilagođen program iz priloga ne radi? Ili ja ne umem da pokrenem servis pod Windows-om. Napominjem da mi je ovo prvo iskustvo te vrste pod Windows-ima. Izbacuje grešku "StartServiceCtrlDispatcher failed".


I na GetLastError ti vraca 1063 (ERROR_FAILED_SERVICE_CONTROLLER_CONNECT)?

Ako je konzolni program koji hoces da startujes iz debug-a ili iz cmd prompta onda ti StartServiceCtrlDispatche vraca false .
Program mora pokrenuti sam Service Control Manager a ne cmd.exe
Tvoj program se mora prvo prijaviti SCM-u (kroz CreateService funkciju )
a zatim se startuje iz SCM-a .
U tu svrhu mozes napraviti command line switch -install -uninstall itd ... tako da ce program sam sebe prijavljivati
i odjavljivati iz SCM-a .

Ovakav nacin otezava debugovanje tvog servisa , tako da u tu svrhu opet mozes dodati cmd line switch
da se ne startuje kao servis kroz "StartServiceCtrlDispatcher" nego kao konzolna aplikacija,
ali da se opet poziva f-ja ServiceMain .

Evo ovde imas lep primer win servisa : http://www.naughter.com/serv.html
cak mozes i zapisivati log u event viewer .




[ Nedeljko @ 16.09.2009. 10:16 ] @
OK, startujem ja njega sa Service intall i dobijam gresku

OpenSCManager failed
[ mmix @ 16.09.2009. 10:30 ] @
Ako si SC otvarao sa NULL, NULL (local comp, default database) onda imas security problem, tj tvoj user verovatno nema pravo da modifikuje SCM bazu.

POgledaj ovaj link

PS: Po defaultu genericki user na Windowsu ne moze da kreira servis jer nema granted SC_MANAGER_CREATE_SERVICE


Evo sad bacih pogled na taj source, ova linija:
Code:
  hSCMgr = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);


Ovaj security nivo imaju samo useri koji su u "Administrators" grupi.

[Ovu poruku je menjao mmix dana 16.09.2009. u 11:52 GMT+1]
[ deerbeer @ 16.09.2009. 10:36 ] @
Da , potrebne su admin privilegije za prijavljivanje na scm
[ Nedeljko @ 16.09.2009. 11:25 ] @
Hvala, samo sto ne radim pod limited user nalogom, pa ipak imam tu poruku o gresci.
[ deerbeer @ 16.09.2009. 11:35 ] @
Probaj ovako :
Code:
 
hScMgr = OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CREATE_SERVICE | SC_MANAGER_LOCK); 

Sa admin privilgijama bi trebalo sigurno da dobijes handle od scm-a
[ Nedeljko @ 16.09.2009. 11:46 ] @
Probah i opet isto. Da li bi neko bio ljubazan da istestira kod kod sebe i onda ga okaci? Koristim Vistu.
[ mmix @ 16.09.2009. 11:49 ] @
SERVICES_ACTIVE_DATABASE ima isti efekat kao NULL a SC_MANAGER_CREATE_SERVICE je podset SC_MANAGER_ALL_ACCESS tako da se svodi na skoro isto.

Kod mene radi OpenSCManager, ali ja jesam administrator na win2k8 masini.
proveri da ti baza nije locked (mada ne bi smelo)

nadji sc.exe u system32

startuj "sc.exe querylock" i vidi dal je baza zakljucana.

Oh, sad vidim da si na visti, jel ti ukljucen UAC?
[ deerbeer @ 16.09.2009. 11:57 ] @
Probao sam kod mene sa tvojim kodom i radi (isto sam na visti )
Eh da ... kako pokreces program (Run as admin ) ?
Znam kad pokrenem visual studio ili program bez run as admin i startujem OpenSCManager vrati NULL .
[ mmix @ 16.09.2009. 12:05 ] @
U svakom slucaju kad resis ovaj problem a nevezano za isti trebao bi da promenis kod da ne trazis SC_MANAGER_ALL_ACCESS vec samo SC_MANAGER_CREATE_SERVICE i ostale privilegije koje ti zaista trebaju. U ovom trenutku to ne predstavlja problem jer je grant za oba na istom nivou, ali to ne znaci da se nece mozda menjati ubuduce. Uvek trazi taman onoliko koiliko ti treba.
[ Nedeljko @ 16.09.2009. 12:10 ] @
Citat:
mmix: Oh, sad vidim da si na visti, jel ti ukljucen UAC?


To je bilo, taj UFO. Sada vise nema te greske.
[ Eurora3D Team @ 16.09.2009. 23:42 ] @
Jedan savet u vezi servisa posto ih je tesko debugovati. Napravi obican console program pa tek kad zavrsis i sve radi ok dodaj onih nekoliko standatdnih funkcija koje u stvari od programa prave servis ...
[ mmix @ 17.09.2009. 08:43 ] @
Ne bih se u potpunosti slozio sa tim, mnogo ljudi zaista koristi taj mehanizam (zapravo varijaciju gde bace ulazni thread u infinite sleep ako servis nije pokrenut iz SCMa i tako sprece gasenje procesa) ali on pomaze samo kod krupnih funkcionalnih propusta u kodu. Servisi imaju poseban rezim rada i to sto sve radi kako treba u admin-level konzoli ne znaci da ce raditi kako treba pod nekim ogranicenim service account-om (local ili network) i bez pristupa desktopu. Zbog takvih security-related bagova ljudi posle dignu ruke i prebace da servis radi pod local system accountom ili nepotrebno forsiraju desktop integraciju kao resenje sto treba izbegavati. Da ne pominjemo razlike u pristupu LAN-u i domenskim servisima sve i sa "bozanskim" local system nalogom.

Postoje razni "koser" nacini za debagovanje servisa a pogodnost je sto retko koji servis radi non-stop, u velikoj vecini servisni proces ima jedan ili vise threadova koji su u WAIT state-u cekajuci neki dogadjaj i najobicniji attach na proces ce te dovesti u mogucnost da okacis breakpoint na izlazu iz wait funkcije. A ako je potrebno debagovati startup kod moze se privremeno ubaciti DebugBreak() na pocetak sto ce otvoriti "attach debuger" prozor sa spiskom registrovanih debugera. U oba slucaja ce servisni proces raditi u svom kontekstu.
[ Eurora3D Team @ 18.09.2009. 02:16 ] @
@mmix Mislio sam na ono najosnovnije debugovanje dok ne dobije neku funkcionalnu celinu. Lakse je pisati i debugovati obicnu aplikaciju. Posle moze da predje na servis i na debugovanje servisa.
Za ovo ostalo se slazem.
[ Nedeljko @ 18.09.2009. 08:28 ] @
Citat:
Eurora3D Team: Jedan savet u vezi servisa posto ih je tesko debugovati. Napravi obican console program pa tek kad zavrsis i sve radi ok dodaj onih nekoliko standatdnih funkcija koje u stvari od programa prave servis ...


Znam za to i to resavam #ifdef-om. U svakom slucaju, hvala!
[ X Files @ 18.09.2009. 10:25 ] @
Citat:
Nedeljko: Znam za to i to resavam #ifdef-om. U svakom slucaju, hvala!

Tako radim i ja.

U principu, sa LogMessage upisujem sve sto je bitno da se vidi u Event Viewer-u, a u nekom CustomLog-u upisujem sve sto ocekujem da se desava sa servisom, sve kriticne tacke i trenutke, koji su pre svega od interesa za programera. Kasnije se suvisni delovi lako zaobidju sa ifdef.

Nije lose imati u vidu i koncept "WatchDog servisa" koji nadzire ispravnost rada glavnog servisa, i po potrebi ga moze recimo restartovati i sl.