Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.01.29;
Скачать: CL | DM;

Вниз

Помогите с сервисом   Найти похожие ветки 

 
parasolka ©   (2006-01-13 12:59) [0]

Надо написать сервис, который бы запускал одну функцию из dll-ки. А именно, функция проверяет указанный каталог и удаляет папки, которые не соответствуют определенным условиям. Импорт dll - статический. Сервис писать хочу не на API, а через стандартный Service Application. Так вот, делаю все как в примере (в хелпе), только вместо ихнего кода вставляю свой (вызов моей функции). Откомпилировал, установил, запустил сервис. Ошибок ни каких, но ничего не происходит, функция не работает. Хотя тот же кусок кода, но в обычном приложении работает должным образом.
В чем дело? Заранее благодарен.


 
Fay ©   (2006-01-13 13:04) [1]

parasolka ©   (13.01.06 12:59)
Ошибка в 17-й строке.


 
Digitman ©   (2006-01-13 13:04) [2]


> В чем дело?


дело в ошибке в 17-й строке


 
kukuikar ©   (2006-01-13 14:18) [3]

Если из [1] и [2] не понял, то ....

КОД ДАВАЙ!!!!!


 
Reindeer Moss Eater ©   (2006-01-13 14:32) [4]

В чем дело?

Служба не нашла DLL.


 
Rouse_ ©   (2006-01-13 15:21) [5]


> Reindeer Moss Eater ©   (13.01.06 14:32) [4]
> В чем дело?
>
> Служба не нашла DLL.

У него статическая загрузка - еслибы не нашла - она бы сразу свалилась...


 
Reindeer Moss Eater ©   (2006-01-13 16:09) [6]

Сервис бы не загрузился.
Так а мы и не знаем, запустился он или нет.
Симптом похож - ничего не происходит


 
Anatoly Podgoretsky ©   (2006-01-13 17:06) [7]

Гипс снимают, клиент уезжает.


 
parasolka ©   (2006-01-14 14:47) [8]

Вот вам код:

unit srv;

interface

uses
 Windows, IniFiles, Messages, SysUtils, Classes, Graphics, Controls, SvcMgr, Dialogs;

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

var
 SRC_SRV: TSRC_SRV;
  implementation

{$R *.DFM}

function CleanDir (dir: String): Integer; stdcall;
external "CleanArh.dll" name "CleanDir";

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

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

procedure TSRC_SRV.ServiceExecute(Sender: TService);
var
res: Integer;
begin

while not terminated do begin
 ServiceThread.ProcessRequests(True);
 res:=CleanDir("C:\VXR_SRC_KADR");
if res=-1 then
 ShowMessage("Error when deleting");
end;

end;
end.


 
parasolka ©   (2006-01-16 11:01) [9]

Концепция изменилась. Теперь Сервис выглядит так:

unit main_srv;

interface

uses
 Windows, Messages, SysUtils, Classes, Controls, SvcMgr, Dialogs,
 ExtCtrls, IniFiles;

type
 TSRC_Service = class(TService)
   Timer1: TTimer;
   procedure Timer1Timer(Sender: TObject);
   procedure ServiceStart(Sender: TService; var Started: Boolean);
   procedure ServiceStop(Sender: TService; var Stopped: Boolean);
   procedure ServiceExecute(Sender: TService);

 private
   { Private declarations }
 public
   function GetServiceController: TServiceController; override;
   { Public declarations }
 end;
 
type
 TCleanDir = function  (dir: String): integer; stdcall;

var
 SRC_Service: TSRC_Service;
 IniFile: TIniFile;
 Path: String;
 CleanDir: TCleanDir;
 LibHandle: HModule;
 res: Integer;

implementation

{$R *.DFM}

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

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

procedure TSRC_Service.Timer1Timer(Sender: TObject);
begin
ShowMessage("Deleting now");
res:=CleanDir("C:\VXR_SRC_KADR");
if res=-1 then
   SRC_Service.Status:=csStopped;
end;

procedure TSRC_Service.ServiceStart(Sender: TService;
 var Started: Boolean);
begin
LibHandle:=LoadLibrary("CleanArh.dll");
if LibHandle<>0 then
 @CleanDir:=GetProcAddress(LibHandle, "CleanDir");
Timer1.Enabled:=True;
end;

procedure TSRC_Service.ServiceStop(Sender: TService; var Stopped: Boolean);
begin
Timer1.Enabled:=False;
FreeLibrary(LibHandle);
end;

procedure TSRC_Service.ServiceExecute(Sender: TService);
begin
while not terminated do
begin
 ServiceThread.ProcessRequests(true);
end;
end;

end.


Все действия проиходят на OnTimer, линковка dll - динамическая. Что самое интересное, сообщение на экран выводится, а вот функция не выполняется.
Что теперь скажите?


 
Fay ©   (2006-01-16 11:08) [10]

2 parasolka ©   (16.01.06 11:01) [9]
А код функции?


 
Digitman ©   (2006-01-16 11:08) [11]

Вызывать ShowMessage() в контексте доп.трэда VCL-приложения не допустимо


 
parasolka ©   (2006-01-16 12:18) [12]

ShowMessage я вызвал для примера, чтобы проверить что он вообще работает.

Чтобы выложить код функции, придется код всей dll класть, так как эта внешняя функция использует несколько функций внутри самой dll. Вы точно этого хотите. Хотя конечно не так уж и много, но все же.


 
Fay ©   (2006-01-16 12:21) [13]

2 parasolka ©   (16.01.06 12:18) [12]
> Вы точно этого хотите
На самом деле я хочу спать. Удачи.


 
parasolka ©   (2006-01-16 12:31) [14]

Не спать!!!
Вот код всей dll-ки.

library CleanArh;

uses
 Windows, Messages, SysUtils, Variants, Classes, Controls,
 Dialogs, StdCtrls, ShellApi, DateUtils, IniFiles;

    RasDial
{$R *.res}

//Вычисление свободного места в Mb

function CalcFreeSpace(DriveLetter: PAnsiChar): integer;
var
FreeAv, Total, FreeSpace: TLargeInteger;
begin
GetDiskFreeSpaceEx(DriveLetter, FreeAv, Total, @FreeSpace);
Result:=FreeSpace div 1048576;
end;

//Функция преобразования имени файла в формате yyyymdd в формат DateTime dd.mm.yyyy

function GetFileDate(fName: String): TDateTime;
var
i: integer;
y, d, m: String;
begin
 y:="";
 d:="";
 m:=fName[5];
 for i:=1 to 4 do
   y:=y+fName[i];
 d:=fName[6]+fName[7];
if (m="A") or (m="a") then m:="10";
if (m="B") or (m="b")then m:="11";
if (m="C") or (m="c")then m:="12";
try
Result:=StrToDateTime(d+"."+m+"."+y);
except
Result:=Date;
ShowMessage("Wrong filename "+fName);
end;
end;

//Функция удаления каталога со всем содержимым
function DelDir(dir: string): Boolean;
var
 fos: TSHFileOpStruct;
begin
 ZeroMemory(@fos, SizeOf(fos));
 with fos do
 begin
   wFunc  := FO_DELETE;
   fFlags := FOF_SILENT or FOF_NOCONFIRMATION;
   pFrom  := PChar(dir + #0);
 end;
 Result := (0 = ShFileOperation(fos));
end;

//Функция очистки каталогов с кадрами.
//Удаляются файлы старше MinDay (см Ini файл) дней.

function CleanDir (dir: String): integer; stdcall;
var
Sr1, Sr2, Sr3: TSearchRec;
IniFile: TIniFile;
space, days: integer;

function IsDirNotation (DirName: String): Boolean;
begin
Result:=(DirName=".") or (DirName="..");
end;

begin     //1
 IniFile:=TIniFile.Create(".\CleanArh.ini");
 days:=IniFile.ReadInteger("OPTIONS", "MinDay", 4);
 space:=IniFile.ReadInteger("OPTIONS", "MinFreeSpace", 500);

if CalcFreeSpace(PChar(ExtractFileDrive(dir)))>space then
begin     //2
 Result:=1;
 Exit;
end;      //2

if dir[Length(dir)]<>"\" then dir:=dir+"\";
if FindFirst(dir+"*", faDirectory, Sr1)=0 then
   repeat
     if ((sr1.Attr and faDirectory)=faDirectory) and not IsDirNotation(sr1.Name) then
     begin   //3
       if FindFirst(dir+sr1.Name+"\*",faDirectory,sr2)=0 then
         repeat
           if ((sr1.Attr and faDirectory)=faDirectory) and not IsDirNotation(sr2.Name) then
           begin   //4
             if FindFirst(dir+sr1.Name+"\"+sr2.Name+"\*",faDirectory,sr3)=0 then
               repeat
                 if ((sr3.Attr and faDirectory)=faDirectory) and not IsDirNotation(sr3.Name) then
                 begin   //5
                   if DaysBetween(Date, GetFileDate(sr3.Name))>days then
                     if not DelDir(dir+sr1.Name+"\"+sr2.Name+"\"+sr3.Name) then begin //6
                      ShowMessage("Error when deleting");
                      Result:=-1;
                      Exit;
                     end;   //6
                 end;     //5
                 until FindNext(sr3)<>0;
           end;    //4
         until FindNext(sr2)<>0;
       end;       //5
   until FindNext(sr1)<>0;

if CalcFreeSpace(PChar(ExtractFileDrive(dir)))>space then Result:=1
else Result:=0;

FindClose(sr1);
FindClose(sr2);
FindClose(sr3);

IniFile.Free;

end;   //1

exports
CleanDir name "CleanDir";

begin
end.


CleanDir должен запускаться в сервисе.


 
Alexander Panov ©   (2006-01-16 12:45) [15]

>parasolka ©   (16.01.06 11:01) [9]

> procedure TSRC_Service.ServiceStart(Sender: TService;
>  var Started: Boolean);
> begin
> LibHandle:=LoadLibrary("CleanArh.dll");
> if LibHandle<>0 then
>  @CleanDir:=GetProcAddress(LibHandle, "CleanDir");
> Timer1.Enabled:=True;
> end;


А ты уверен, что у тебя библиотека загружена?


 
parasolka ©   (2006-01-16 12:51) [16]

Думаю, что да, потому что тот же кусок кода, но в обычном приложении работает должным образом.


 
Alexander Panov ©   (2006-01-16 12:54) [17]


> Думаю, что да, потому что тот же кусок кода, но в обычном
> приложении работает должным образом.


Как ты думаешь, как находит твоя программа эту DLL в обычном приложении?
А как в сервисе?


 
Desdechado ©   (2006-01-16 12:54) [18]

тебе уже говорили, что взаимодействие с рабочим столом в сервисах (и DLL для них) не допускается
кстати, и неплохо бы все вызовы, могущие потенциально вывалиться на AV с показом системных сообщений, тоже в try-блок спрятать
если хочешь проверить или показать ошибку - пиши в журнал или в файл


 
Игорь Шевченко ©   (2006-01-16 13:07) [19]


> тебе уже говорили, что взаимодействие с рабочим столом в
> сервисах (и DLL для них) не допускается


При установке соответствующей гайки очень даже допускается


 
Digitman ©   (2006-01-16 15:10) [20]


> parasolka ©   (16.01.06 12:18) [12]
> ShowMessage я вызвал для примера, чтобы проверить что он
> вообще работает.


Еще раз повторяю - вызывать ShowMessage() чв дополнительном кодовом потоке VCL-приложения НЕДОПУСТИМО ! Хоть для примера, хоть не для примера ..

Разберись сначала с этим, а потом уже будешь маяться со своей DLL



Страницы: 1 вся ветка

Текущий архив: 2006.01.29;
Скачать: CL | DM;

Наверх




Память: 0.53 MB
Время: 0.032 c
2-1136902971
Vegasnator
2006-01-10 17:22
2006.01.29
Помогите новичку!


3-1133344874
АлександрМ
2005-11-30 13:01
2006.01.29
Экранирование кавычек в SQL


6-1128707503
Logan
2005-10-07 21:51
2006.01.29
Непонятки с отправкой почты Indy9


2-1136955770
Rubey
2006-01-11 08:02
2006.01.29
Работа с MEMO


9-1121634452
LexaDup
2005-07-18 01:07
2006.01.29
Линия видимости в GLSCene