Windows servis uygulaması geliştirirken kolay geliştirme ortamı sağlamak ...

Yazdığınız makaleleri ve üyelerimizin işine yarayacağını düşündüğünüz kodlarınızı gönderebilirsiniz. Bu foruma soru sormayın!
Cevapla
Kullanıcı avatarı
sabanakman
Kıdemli Üye
Mesajlar: 2977
Kayıt: 17 Nis 2006 07:11
Konum: Ah bi Antalya olaydı keşke (Ankara)

Windows servis uygulaması geliştirirken kolay geliştirme ortamı sağlamak ...

Mesaj gönderen sabanakman » 15 Şub 2016 12:26

İyi günler. Windows servis uygulamaları geliştirirken yapılan testlerin zorluğunu çeken bilir :mrgreen: . İşin aslı, servis uygulamasında birazcık şekil değişikliği ile bir parametre veya debug esnasında windows uygulamasıymış gibi çalışması sağlanarak daha konforlu testler yapmak mümkün olmaktadır. Mesela bir servis uygulamasının .dpr dosyası aşağıdaki gibi olacaktır.

Kod: Tümünü seç

program BenimServis;

uses
  Vcl.Forms,
  Vcl.SvcMgr,
  untServis in 'untServis.pas' {Servis: TService};

{$R *.RES}

begin
  if not Application.DelayInitialize or Application.Installing then
    Application.Initialize;
  Application.CreateForm(TServis, Servis);
  Application.Run;
end.
Haliyle böyle bir uygulamanın çalışma testlerini yapmak, servisi kurmak-başlatmak ve/veya yeni halini tekrar kurmadan önce servisi durdurmak (ve hatta bazen kaldırmak) gerekebilmektedir. Bu durum basit bir müdahale ile windows masaüstü uygulaması gibi çalıştırarak çok pratik hale gelebilir aslında. Yukarıdaki projeye basit bir form ekleyip, bu form üzerinde aktif bir timer ayarladıktan sonra bu timer içinden de servis için çalışan metodu çağırmak yeterli olacaktır. Tabi önce .dpr dosyasına aşağıdaki gibi bir eklenti yapmak gerekmektedir.

Kod: Tümünü seç

program BenimServis;

uses
  System.SysUtils,
  Vcl.Forms,
  Vcl.SvcMgr,
  untServis in 'untServis.pas' {Servis: TService},
  untAnaForm in 'untAnaForm.pas' {FormAna: TForm};

{$R *.RES}

var Delphiden, isDesktop:Boolean;

begin
  isDesktop:=SameText(ParamStr(1),'/win'); //masaüstü gibi çalışsın isteniyorsa ilk önce /win parametresi verilir
{$WARNINGS OFF}
  Delphiden:=DebugHook<>0; //delphiden f9 la mı çalışıyor
{$WARNINGS ON}
  if Delphiden or isDesktop then begin //masaüstü uygulaması gibi çalışması için FormAna'da timer olmalı ve buradan servis metodu çalışacak
    Vcl.Forms.Application.Initialize;
    Vcl.Forms.Application.MainFormOnTaskbar := True;
    Vcl.Forms.Application.CreateForm(TServis, Servis);
    Vcl.Forms.Application.CreateForm(TFormAna, FormAna);
    Vcl.Forms.Application.Run;
  end else begin //uygulama normal servis olarak çalışır
    if not Vcl.SvcMgr.Application.DelayInitialize or Vcl.SvcMgr.Application.Installing then
      Vcl.SvcMgr.Application.Initialize;
    Vcl.SvcMgr.Application.CreateForm(TServis, Servis);
    Vcl.SvcMgr.Application.Run;
  end;
end.
Bu şekilde hazırlanan proje test ederken masaüstü uygulaması gibi çalışarak çok daha pratik bir geliştirme fırsatı sağlayacaktır.

Yine benzeri bir mantıkla DataSnap servis uygulamasında da aynı durum geçerli olacaktır. Mesela aşağıdaki gibi bir DataSnap Server Servis uygulamamız olsun.

Kod: Tümünü seç

program VeriSaglayici;

uses
  Vcl.SvcMgr,
  dmServerDataModule in 'dmServerDataModule.pas' {Dmod: TDataModule},
  ServerMethodsUnitVeriSaglayici in 'ServerMethodsUnitVeriSaglayici.pas' {ServerMethodsVeriVer: TDSServerModule},
  ServerContainerUnitVeriSaglayici in 'ServerContainerUnitVeriSaglayici.pas' {VeriVerContainer: TService};

{$R *.RES}

begin
  if not Application.DelayInitialize or Application.Installing then
    Application.Initialize;
  Application.CreateForm(TDmod, Dmod);
  Application.CreateForm(TVeriVerContainer, VeriVerContainer);
  Application.Run;
end.
Bu standart oluşan bir DataSnap Servis uygulamasının yapısı. Buna da yukarıda yapılana benzer bir müdahale ile, rahat çalışma testleri yapabileceğimiz masaüstü uygulama yapısında bir şekil verebiliriz.

Kod: Tümünü seç

program VeriSaglayici;

uses
  System.SysUtils,
  Vcl.Forms,
  Vcl.SvcMgr,
  dmServerDataModule in 'dmServerDataModule.pas' {Dmod: TDataModule},
  ServerMethodsUnitVeriSaglayici in 'ServerMethodsUnitVeriSaglayici.pas' {ServerMethodsVeriVer: TDSServerModule},
  ServerContainerUnitVeriSaglayici in 'ServerContainerUnitVeriSaglayici.pas' {VeriVerContainer: TService},
  untAnaForm in 'untAnaForm.pas' {frmAna: TForm};

{$R *.RES}

var Delphiden, isDesktop:Boolean;

begin
  isDesktop:=SameText(ParamStr(1),'/win'); //masaüstü gibi çalışsın isteniyorsa ilk önce /win parametresi verilir
{$WARNINGS OFF}
  Delphiden:=DebugHook<>0; //delphiden f9 la mı çalışıyor
{$WARNINGS ON}
  if Delphiden or isDesktop then begin //masaüstü uygulaması gibi çalışması için FormAna'da timer olmalı ve buradan servis metodu çalışacak
    Vcl.Forms.Application.Initialize;
    Vcl.Forms.Application.MainFormOnTaskbar := True;
    Vcl.Forms.Application.CreateForm(TDmod, Dmod);
    Vcl.Forms.Application.CreateForm(TVeriVerContainer, VeriVerContainer);
    Vcl.Forms.Application.CreateForm(TfrmAna, frmAna);
    Vcl.Forms.Application.Run;
  end else begin
    if not Vcl.SvcMgr.Application.DelayInitialize or Vcl.SvcMgr.Application.Installing then
      Vcl.SvcMgr.Application.Initialize;
    Vcl.SvcMgr.Application.CreateForm(TDmod, Dmod);
    Vcl.SvcMgr.Application.CreateForm(TVeriVerContainer, VeriVerContainer);
    Vcl.SvcMgr.Application.Run;
  end;
end.
Yalnız bu sefer ana formda bir Timer'a ihtiyaç yoktur. Bunun yerine sadece VeriVerContainer üzerinde bulunan TDSServer nesnesinin AutoStart özelliğinin True olması yeterlidir. Bizim DataSnap Server uygulamamız delphi üzerinden çalıştırılınca windows uygulaması gibi davranacak ama yaptığımız proje normalde windows servis uygulaması olacaktır. İyi çalışmalar.
Şaban Şahin AKMAN
_________________
Derin olan kuyu değil kısa olan iptir. - .

ertank
Üye
Mesajlar: 902
Kayıt: 11 Eyl 2015 11:45

Re: Windows servis uygulaması geliştirirken kolay geliştirme ortamı sağlamak ...

Mesaj gönderen ertank » 07 Mar 2016 12:00

Merhaba,

Bir WebService sunucu uygulaması (File->Other->WebService->SOAP Server Application) için Delphi içindeki Wizard kullanıldığı zaman Vcl.Form uygulaması olarak örnek kod oluşturuyor. Bu kodu servis olarak dönüştürmek üzerine bir örnek vermeniz mümkün müdür?

Benim çözemediğim nokta Servis başlat-durdur için Form ekranında butonlar var ve servis ile ilgili nesne bu form üzerine OnCreate içinde oluşturuluyor. Bu formu servis modunda hiç çalıştırmaz isem port dinlemesi yapmayacak. Bu durumda port dinlemesi yapması için gerekli kodu nereye ve ne şekilde yazmam gerektiğini bilmiyorum.

Teşekkürler.

Kullanıcı avatarı
sabanakman
Kıdemli Üye
Mesajlar: 2977
Kayıt: 17 Nis 2006 07:11
Konum: Ah bi Antalya olaydı keşke (Ankara)

Re: Windows servis uygulaması geliştirirken kolay geliştirme ortamı sağlamak ...

Mesaj gönderen sabanakman » 07 Mar 2016 12:57

Üzerinde deneme yapma şansım yok ama servis uygulama üzerinde herşey VCL ile oluşturulan projede olduğu gibi kullanmak gerekecektir. Ana formda kullanılan, "FServer: TIdHTTPWebBrokerBridge;" nesnesi servis formunda da aynı şekilde tanımlanıp onCreate olayında oluşturulmalıdır. Bu sefer uygulamayı durdurup başlatan kodlar butona değil, servis formundaki onStart, onStop (ve hatta onPause, onContinue) olaylarında yazılarak bir SOAP Server Servis uygulaması geliştirebilirsiniz.
Şaban Şahin AKMAN
_________________
Derin olan kuyu değil kısa olan iptir. - .

ertank
Üye
Mesajlar: 902
Kayıt: 11 Eyl 2015 11:45

Re: Windows servis uygulaması geliştirirken kolay geliştirme ortamı sağlamak ...

Mesaj gönderen ertank » 07 Mar 2016 01:56

Normal bir Servis uygulaması oluştur dediğimde formu olmayan bir Unit oluşturdu. İçinde sizin bahsettiğiniz OnCreate, OnStart, OnStop, OnPause, OnContinue olayları bu unit içinde mevcut değil. Acaba manuel eklenmesi gereken olaylar mıdır?

Oluşturulan Program aşağıdadır.

Kod: Tümünü seç

program Project6;

uses
  Vcl.SvcMgr,
  Unit7 in 'Unit7.pas' {Service7: TService};

{$R *.RES}

begin
  // Windows 2003 Server requires StartServiceCtrlDispatcher to be
  // called before CoRegisterClassObject, which can be called indirectly
  // by Application.Initialize. TServiceApplication.DelayInitialize allows
  // Application.Initialize to be called from TService.Main (after
  // StartServiceCtrlDispatcher has been called).
  //
  // Delayed initialization of the Application object may affect
  // events which then occur prior to initialization, such as
  // TService.OnCreate. It is only recommended if the ServiceApplication
  // registers a class object with OLE and is intended for use with
  // Windows 2003 Server.
  //
  // Application.DelayInitialize := True;
  //
  if not Application.DelayInitialize or Application.Installing then
    Application.Initialize;
  Application.CreateForm(TService7, Service7);
  Application.Run;
end.
Oluşturulan Unt aşağıdadır.

Kod: Tümünü seç

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.SvcMgr, Vcl.Dialogs;

type
  TService7 = class(TService)
  private
    { Private declarations }
  public
    function GetServiceController: TServiceController; override;
    { Public declarations }
  end;

var
  Service7: TService7;

implementation

{$R *.dfm}

procedure ServiceController(CtrlCode: DWord); stdcall;
begin
  Service7.Controller(CtrlCode);
end;

function TService7.GetServiceController: TServiceController;
begin
  Result := ServiceController;
end;

end.

Cevapla