Как написать NT Сервис в C++ Builder 4
Для создания приложения, которое является Win32
сервисом выберите File | New, а затем выберите Service
Application на странице New Items:
В проект автоматически будет добавлена
глобальная переменная Application, которая будет
иметь тип TServiceApplication. Как только Вы создадите
сервисное приложение, то сразу увидите окошко,
которое отвечает за сервис (TService). У Сервиса
так же есть свойства и обработчики событий,
которые можно настроить в Object Inspector. Как только
объект TService будет добавлен, то приложение уже
не сможет генерировать стандартные события и
оконные сообщения.
Пример: Ниже приведён пример сервиса,
который имеет TServerSocket, порт которого установлен в
80. Так же этот пример создаёт текстовый файл в
директории C:\Temp с именем WebLogxxx.log (где xxx
это ThreadID). Каждым портом в системе может владеть
только одно приложение, поэтому если у Вас
запущен веб сервер, то необходимо его временно
выключить (остановить сервис).
Для просмотра результатов, запустите браузер и
в строке адреса наберите 'localhost' (без кавычек).
Браузер выдаст тайм-аут, однако теперь появится
файл weblogxxx.log в директории C:\temp.
- В File | New в диалоге New Items выберите Service
Application. Появится окно Service1. Из закладки Internet в
палитре компонентов добавьте компонент ServerSocket
в окно сервиса (Service1).
- Далее добавьте в класс TService1, переменную типа TMemoryStream.
Заголовочный файл будет выглядеть следующим
образом:
//-----------------------------------------------------------
#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
|
- Далее выберите компонент ServerSocket1, в Object Inspector,
сделайте двойной клик по событию OnClientRead и
добавьте следующий код в обработчик события:
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);
}
}
|
- В заключение, выберите Service1 и добавьте
следующий код в обработчик события OnExecute:
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;
}
}
|
|