[ franjo_tahi @ 04.12.2008. 08:22 ] @
Znam da na net-u ima dosta upustava kako se radi servis pomoću Delphi-a, ali je malo vremena za učenje, a inaće se na bavim tom vrstom programa.

Moram napraviti prog. koji će u zadato vrijeme spojiti se na bazu, izdvojiti određene podatke, kreirati nekoliko txt file-ova i postaviti ih na ftp. Imam normalin win32 prog. koji to radi, a sada ga treba preraditi da radi kao servis.

Zahtjev je da se vrti kao servis.

Pokušao sam napraviti, nešto jednostavno, ali: kada pokrenem program, u servisima se pojavi na nekolilko sekundi i odmah nestane.

Da li netko zna u čemu je problem ili možda ima kakav jednostavan source koji mi može poslati?
[ savkic @ 04.12.2008. 10:03 ] @
Napravi novi Service projekat (File/Other/New-Service application), dodaj OnExecute handler i u njemu dodaj potrebnu obradu ili izdvoj postojeći kod u novu klasu (može i thread) koju ćeš pozvati iz tog eventa, ne zaboravi da dodaš i ProcessRequests.
[ franjo_tahi @ 04.12.2008. 12:08 ] @
savkicu, hvala

Ovo mi je malo preskračen opis.
Gdje da dodam ProcessRequests?

Ako imaš (ili možeš napraviti :) ) ljusku - app koja će ostati kao seris, a u proc u kojoj se izvrašava ono što treba upisati samo komentar npr:
// ovdje ide kod


Hvala unaprijed
[ Vic @ 04.12.2008. 12:18 ] @
Rad sa servisnom aplikacijom je jako slican kao i sa svakom drugom aplikacijom. Stavi onSstart


procedure TMojaAplikacija.ServiceStart(Sender: TService;
var Started: Boolean);
begin
startTimer();
started:=true;

end;

procedure TMojaAPlikacija.startTimer();
begin
timer.interval:=vrednost osvezavanja;
end;

Dodaj on timer event i kada se uslovi poklope, nek aplikacija izvuce podatke i obradi ih (taj deo imas uradjen koliko sam razumeo)
[ franjo_tahi @ 04.12.2008. 18:36 ] @
Kreirao sam app File->New->Other->Delphi Projects->Service Application

u unit1 koji je automatski kreiran, u Events OnStart sam dodao Started := true;

tako da imam:

Code:

procedure TService1.ServiceStart(Sender: TService; var Started: Boolean);
begin
   Started := true;
end;


Nakon Run iz Delphi-a ili compile pa nakon toga pokretanje programa Project1.exe
u Task Menageru->Processes se pojavi Project1,
u Task Menageru->Services se ne pojavi ništa novog

Nakon cca 10 sekundi, program se zaustavi sam i nestane iz procesa. Isto se dogodi bez obzira da li je startan kao program ili iz Delphi-a.

Što mi nedostaje?
[ Vic @ 04.12.2008. 18:40 ] @
Service se ne pokrece tako sto startujes project exe. U start meniju idi na browse, nadji svoj exe i dodaj Project.exe /install. Nakon toga ces imati u servisima service Project1 ili sta vec, pa ga odatle startujes.
[ franjo_tahi @ 04.12.2008. 18:46 ] @
Kako postaviti da se starta svaki pout nakor restarta kompa?
[ Vic @ 04.12.2008. 18:51 ] @
Taj deo se regulise u servisima pod opcijom startup type, znaci stvar je windowsa a ne samog programiranja
[ X Files @ 04.12.2008. 19:09 ] @
Servisi se prvo instaliraju:
Project1.exe /install
... pa se tek onda vrsi startovanje, pauziranje, zaustavljanje i sl.

Deinstaliraju se slicno:
Project1.exe /uninstall

(mozes iz konzole da pokrenes instaliranje/deinstaliranje ili najbolje napravi dva shortcuta sa parametrima /install i /unistall, da bi lakse testirao program)
[ X Files @ 04.12.2008. 19:14 ] @
A mozes da kontrolisanje servisa: startovanje, zaustavljnje, pauziranje, nastavljanje i korisnicki definisane poruke odradis i kao zasebnu aplikaciju.

Ovde mozes da pogledas jedan DEMO koji sam radio na slicnu temu:
http://www.elitesecurity.org/t253787-0#1525450

Iako je kod u C++ Builderu, sve je u VCL-u pa ces se lako snaci oko detalja.



[ franjo_tahi @ 04.12.2008. 19:42 ] @
Zahvaljujem na odgovorima. Idem to isprobati. Valjda će raditi :)

Još jedno pitanje: pristup bazama (Firebird) je normalan, kao u običnom programu?




A lijepo sam to mogao napraviti kao normalni prog bez sveg s...a
[ Vic @ 04.12.2008. 19:44 ] @
Pristup FB je standardan naravno.
[ franjo_tahi @ 05.12.2008. 14:43 ] @
Naparvio sam service. Kad sam imo samo ljusku, mogao sam ga startati.

Dodao sam procedure za učitavanje parametara iz txt file-a. Koristim:

stringlist.loadfromfile('ime file-a');
parametar := stringlist['ime parametra'];

Dodao sam i konekciju na fdb bazu, koju starta timer i koja se ne otvara...

Install prođe ok (recimo, jer se serivce ne starta)

u servisima kad pokušam startati svoj srvis javi mi sljedeću poruku:

"The Service1 service on Local Computer started and then stopped. Some services stop automatically if they are not use by other services or programs."

Izbacio sam pozivanje bilo koje procedure, a timer mi je disabled.


kreirao sam proc:
Code:

procedure TService1.ServiceStart(Sender: TService; var Started: Boolean);
begin
   Started := true;
   WriteLog('*** Load service: ' + DateTimeToStr(now));
end;

procedure TService1.WriteLog(Value: string);
var tf: TextFile;
begin
   try
      AssignFile(tf, 'c:\program files\moj_servis\webupdate.log');
      Append(tf);
      Writeln(Value);
   finally
      Close(tf);
   end;
end;


file: 'c:\program files\moj_servis\webupdate.log' postoji, ali se ne upiše tekst koji bi, pretpostavljam trebao čim uđe u proceduru ServiceStart.

Pomoć !!!


[ Vic @ 05.12.2008. 14:48 ] @
Koliko se ja secam, txt ili ini fajl koji pozivas bi trebao da bude u system32.
[ obucina @ 05.12.2008. 15:14 ] @
Citat:
franjo_tahi: Još jedno pitanje: pristup bazama (Firebird) je normalan, kao u običnom programu?

Da, ali ako tvoj servis radi na istoj masini kao i FB server na koji se povezuje, moras postaviti Dependency za svoj servis, tj da kazes da tvoj servis zavisi od Firebird servisa, da se ne dogodi da pokusas da pristupi podacima dok FB server ne radi. Dependency postavljas, pogodi gde - property Dependencies. Dodaj jedan i u listi izaberi Firebird Server.

Citat:
franjo_tahi: file: 'c:\program files\moj_servis\webupdate.log' postoji, ali se ne upiše tekst koji bi, pretpostavljam trebao čim uđe u proceduru ServiceStart.

Naravno da se ne upise kada ne pises u fajl vec na standardni izlaz. writeln(tf, Value);
[ savkic @ 05.12.2008. 17:34 ] @
> u servisima kad pokušam startati svoj srvis javi mi sljedeću poruku:
> "The Service1 service on Local Computer started and then stopped. Some services stop automatically if they are not use by other services or programs."

TService mora imati OnExecute handler, bez njega nema šta da radi i može samo da se zatvori.

[ X Files @ 05.12.2008. 18:34 ] @
^
Citat:

TService mora imati OnExecute handler, bez njega nema šta da radi i može samo da se zatvori.

Ako se ne varam, ipak postoji izuzetak od ovog pravila.
Ako se u OnStart pokrene zaseban thread ili ako se koristi TIdTCPServer u servisnoj aplikaciji, u njemu se moze handle-ovati sav saobracaj.

Inace, primetio sam da ljudi poprilicno pogresno koriste OnExecute() i otuda vecina problema.
[ savkic @ 05.12.2008. 19:43 ] @
> Ako se ne varam, ipak postoji izuzetak od ovog pravila.
> Ako se u OnStart pokrene zaseban thread ili ako se koristi TIdTCPServer u servisnoj aplikaciji, u njemu se moze handle-ovati sav saobracaj.

TService spawnuje novi thread i u kontekstu tog threada se izvršava OnExecute, kada se završi taj thread i TService završava. Taj korišćeni thread je standardni TThread naslednik i on se automatski završava po okončanju Execute procedure što se odmah dešava pošto nema OnExecute handlera.

Spawnovanje novog threada u OnStart bi imalo uticaja na opisani proces samo ako se OnStart nikada ne završi, ali time se blokira čitav servis i on više ne može obradjivati poruke (zapravo moguće je ali to zahteva ručno hakovanja).

TIdTCPServer startuje jedan listener thread i po jedan thread za svaku klijentsku konekciju, on jeste dovoljan za handlovanje klijenata, međutim OnExecute i ProcessRequests u njemu su obavezni.