Delphi Clinic C++Builder Gate Training & Consultancy Delphi Notes Weblog Dr.Bob's Webshop
Dr.Bob's Delphi Notes Dr.Bob's Kylix Kicks
 Borland C++Builder 4 NT Services
See Also: C++Builder Papers and Columns

How To Write NT Services with C++Builder 4
To create an application that implements a Win32 service, Choose File | New, and select Service Application from the New Items page:

C++Builder 4 Object Repository

This adds a global variable named Application to your project, which is of type TServiceApplication.
Once you have created a service application, you will see a window in the designer that corresponds to a service (TService). Implement the service by setting its properties and event handlers in the Object Inspector. You can add additional services to your service application by choosing Service from the new items dialog. Do not add services to an application that is not a service application. While a TService object can be added, the application will not generate the requisite events or make the appropriate Windows calls on behalf of the service.

Example: This service has a TServerSocket whose port is set to 80. This is the default port for Web Browsers to make requests to Web Servers and for Web Servers to make responses to Web Browsers. This particular example produces a text document in the C:\Temp directory called WebLogxxx.log (where xxx is the ThreadID). There should be only one Server listening on any given port, so if you have a web server, you should make sure that it is not listening (the service is stopped).

To see the results: open up a web browser on the local machine and for the address, type 'localhost' (with no quotes). The Browser will time out eventually, but you should now have a file called weblogxxx.log in the C:\temp directory.

  1. To create the example, choose File | New and select Service Application from the New Items dialog. You will see a window appear named Service1. From the Internet page of the component palette, add a ServerSocket component to the service window (Service1).
  2. Next, add a private data member of type TMemoryStream to the TService1 class. The header for your unit should now look something like this:

    //-----------------------------------------------------------
    #ifndef Unit1H
    #define Unit1H
    //-----------------------------------------------------------
    
    #include <SysUtils.hpp>
    #include <Classes.hpp>
    #include <SvcMgr.hpp>
    #include <ScktComp.hpp>
    //-----------------------------------------------------------
    
    class TService1 : public TService
    {
    __published: // IDE-managed Components
      TServerSocket *ServerSocket1;
    
    private: // User declarations
      TMemoryStream *Stream; // add this line here
    
    public:  // User declarations
      __fastcall TService1(TComponent* Owner);
      PServiceController __fastcall GetServiceController(void);
      friend void __stdcall ServiceController(unsigned CtrlCode);
    };
    //-----------------------------------------------------------
    
    extern PACKAGE TService1 *Service1;
    //-----------------------------------------------------------
    
    #endif

  3. Next, select ServerSocket 1, the component you added in step 1. In the Object Inspector, double click the OnClientRead event and add the following event handler:

    void __fastcallTService1::ServerSocket1ClientRead(TObject
          *Sender, TCustomWinSocket *Socket)
    {
      char *Buffer = NULL;
      int len = Socket->ReceiveLength();
      while (len > 0)
      {
        try
        {
          Buffer = (char *)malloc(len);
          Socket->ReceiveBuf((void *)Buffer, len);
          Stream->Write(Buffer, strlen(Buffer));
        }
        __finally
        {
          free(Buffer);
        }
        Stream->Seek(0, soFromBeginning);
        AnsiString LogFile = "C:\\Temp\\WebLog";
        LogFile = LogFile + IntToStr(ServiceThread->ThreadID)
                          + ".log";
        Stream->SaveToFile(LogFile);
      }
    }

  4. Finally, select Service1 by clicking in the window's client area (but not on the ServiceSocket). In the Object Inspector, double click the OnExecute event and add the following event handler:

    void __fastcall TService1::Service1Execute(TService *Sender)
    {
      Stream = new TMemoryStream();
      try
      {
        ServerSocket1->Port = 80; // WWW port
        ServerSocket1->Active = true;
        while (!Terminated)
           ServiceThread->ProcessRequests(false);
        ServerSocket1->Active = false;
      }
      __finally
      {
        delete Stream;
      }
    }

In order to install the NT Services, be sure to read the article on Performing a Service.


This webpage © 2000-2017 by Bob Swart (aka Dr.Bob - www.drbob42.com). All Rights Reserved.