因工作需要,编写了一个系统服务程序。用来监视指定的系统服务是否停止。并在停止的时候,重新启动该服务
此程序在长期使用后,占用内存不断加大,曾经达到过180M。请高手指点一下,此服务程序存在的BUG及解决方法。
谢谢~~~~~~
unit Unit1;interfaceuses
Windows, Messages, SysUtils, Classes, Graphics, Controls, SvcMgr, Dialogs,
ExtCtrls,Winsvc,IniFiles,DateUtils, dcInternal, dcDiskScanner;type
Tlindamis_watch = class(TService)
dcDiskScanner1: TdcDiskScanner;
procedure ServiceExecute(Sender: TService);
procedure Timer1Timer(Sender: TObject);
procedure dcDiskScanner1FileFound(Sender: TObject; const FileName,
FileType: String; const FileSize: Extended;
const FileTime: TDateTime; const FileAttributes: TdcScanAttributes;
const LargeIcon, SmallIcon: TIcon; SysImageIndex,
TotalFiles: Integer; const TotalSize: Extended);
private
{ Private declarations }
public
servicenamelist:Tstringlist;
function GetServiceController: TServiceController; override;
{ Public declarations }
end;var
lindamis_watch: Tlindamis_watch;
MYInterval:integer;
mdmppath:string;
implementation{$R *.DFM}function RunServies(svr:String):Boolean;//启动某个服务;
var
schService:SC_HANDLE;
schSCManager:SC_HANDLE;
ssStatus:TServiceStatus;
Argv:PChar;
begin
schSCManager:=OpenSCManager(nil,nil,SC_MANAGER_ALL_ACCESS);
schService:=OpenService(schSCManager,Pchar(svr),SERVICE_ALL_ACCESS);
result := True;
try
if StartService(schService,0,Argv) then
begin
while (QueryServiceStatus(schService,ssStatus)) do
begin
Sleep(500);
//Application.ProcessMessages;
if ssStatus.dwCurrentState=SERVICE_START_PENDING then
Sleep(500)
else
Break;
end;//while
if ssStatus.dwCurrentState=SERVICE_RUNNING then
result := True
else
result := False;
end
else
result := False;
finally
CloseServiceHandle(schService);
CloseServiceHandle(schSCManager);
end;
end;
function StopServies(svr:String):Boolean;//停止某个服务;
var
schService:SC_HANDLE;
schSCManager:SC_HANDLE;
ssStatus:TServiceStatus;
begin
schSCManager:=OpenSCManager(nil,nil,SC_MANAGER_ALL_ACCESS);
schService:=OpenService(schSCManager,Pchar(svr),SERVICE_ALL_ACCESS);
try
if ControlService(schService,SERVICE_CONTROL_STOP,ssStatus) then
begin
Sleep(1000);
while (QueryServiceStatus(schService,ssStatus)) do
begin
//Application.ProcessMessages;
if ssStatus.dwCurrentState=SERVICE_STOP_PENDING then
Sleep(1000)
else
break;
end; //while
if ssStatus.dwCurrentState=SERVICE_STOPPED then
result := True
else
result := False;
end
else
result := False;
finally
CloseServiceHandle(schService);
CloseServiceHandle(schSCManager);
end;
end;function SplitString(const source,ch:string):tstringlist;var temp:string; i:integer;begin result:=tstringlist.Create; temp:=source; i:=pos(ch,source); while i<>0 do begin result.Add(copy(temp,0,i-1)); delete(temp,1,i); i:=pos(ch,temp); end; result.Add(temp);end;
procedure ServiceController(CtrlCode: DWord); stdcall;
begin
lindamis_watch.Controller(CtrlCode);
end;function Tlindamis_watch.GetServiceController: TServiceController;
begin
Result := ServiceController;
end;
procedure Tlindamis_watch.ServiceExecute(Sender: TService);
var
oIniFile:TIniFile;
IniFileName:string;
// i:integer;
servicename:string; BeginTime : TDateTime;
begin IniFileName := 'c:\windows\mywatch.ini';
oIniFile := TIniFile.Create(IniFileName);
servicename:= oIniFile.ReadString('通用', '服务列表', '');
mdmppath := oIniFile.ReadString('通用', 'mdmp路径', ''); servicenamelist:=SplitString(servicename,',');
//oIniFile.Free; myInterval:=strtoint(oIniFile.ReadString('通用', '检测间隔', '10000'));
// Timer1.Enabled := True;
BeginTime := GetTickCount(); while not Terminated do begin
Sleep(myInterval);
ServiceThread.ProcessRequests(False);
// if MilliSecondOf(GetTickCount()-BeginTime)>=myInterval then Timer1Timer(self);
dcDiskScanner1.Folder:= mdmppath;
dcDiskScanner1.Execute;
BeginTime := GetTickCount(); end;
//Timer1.Enabled := False;
end;procedure Tlindamis_watch.Timer1Timer(Sender: TObject);
var
schService:SC_HANDLE;
schSCManager:SC_HANDLE;
ssStatus:TServiceStatus;
servicename1:string;
i:integer;{ oIniFile:TIniFile;
IniFileName:string; servicename:string;
servicenamelist:Tstringlist;}
begin{
IniFileName := '.\mywatch.ini';
oIniFile := TIniFile.Create(IniFileName);
servicename:= oIniFile.ReadString('通用', '服务列表', ''); servicenamelist:=SplitString(servicename,',');}
for i:=0 to servicenamelist.Count-1 dobegin
servicename1:=servicenamelist[i];
//LogMessage( 'Starting '+servicename1 , EVENTLOG_INFORMATION_TYPE );
// servicename1:='Alerter';
schSCManager:=OpenSCManager(nil,nil,SC_MANAGER_ALL_ACCESS);
schService:=OpenService(schSCManager,pchar(servicename1),SERVICE_ALL_ACCESS);
if QueryServiceStatus(schService,ssStatus) then
if ssStatus.dwCurrentState=SERVICE_RUNNING then
begin end
else
if ssStatus.dwCurrentState= SERVICE_STOPPED then
begin
if RunServies(servicename1) then LogMessage( 'Starting '+servicename1+' 成功,检测间隔为'+inttostr(MYInterval)+'毫秒' , EVENTLOG_INFORMATION_TYPE );
end;
end;
//oIniFile.Free;
end;
procedure Tlindamis_watch.dcDiskScanner1FileFound(Sender: TObject;
const FileName, FileType: String; const FileSize: Extended;
const FileTime: TDateTime; const FileAttributes: TdcScanAttributes;
const LargeIcon, SmallIcon: TIcon; SysImageIndex, TotalFiles: Integer;
const TotalSize: Extended);
begin
if deletefile(FileName) then
LogMessage( '删除 '+FileName+' 成功' , EVENTLOG_INFORMATION_TYPE );end;end.
此程序在长期使用后,占用内存不断加大,曾经达到过180M。请高手指点一下,此服务程序存在的BUG及解决方法。
谢谢~~~~~~
unit Unit1;interfaceuses
Windows, Messages, SysUtils, Classes, Graphics, Controls, SvcMgr, Dialogs,
ExtCtrls,Winsvc,IniFiles,DateUtils, dcInternal, dcDiskScanner;type
Tlindamis_watch = class(TService)
dcDiskScanner1: TdcDiskScanner;
procedure ServiceExecute(Sender: TService);
procedure Timer1Timer(Sender: TObject);
procedure dcDiskScanner1FileFound(Sender: TObject; const FileName,
FileType: String; const FileSize: Extended;
const FileTime: TDateTime; const FileAttributes: TdcScanAttributes;
const LargeIcon, SmallIcon: TIcon; SysImageIndex,
TotalFiles: Integer; const TotalSize: Extended);
private
{ Private declarations }
public
servicenamelist:Tstringlist;
function GetServiceController: TServiceController; override;
{ Public declarations }
end;var
lindamis_watch: Tlindamis_watch;
MYInterval:integer;
mdmppath:string;
implementation{$R *.DFM}function RunServies(svr:String):Boolean;//启动某个服务;
var
schService:SC_HANDLE;
schSCManager:SC_HANDLE;
ssStatus:TServiceStatus;
Argv:PChar;
begin
schSCManager:=OpenSCManager(nil,nil,SC_MANAGER_ALL_ACCESS);
schService:=OpenService(schSCManager,Pchar(svr),SERVICE_ALL_ACCESS);
result := True;
try
if StartService(schService,0,Argv) then
begin
while (QueryServiceStatus(schService,ssStatus)) do
begin
Sleep(500);
//Application.ProcessMessages;
if ssStatus.dwCurrentState=SERVICE_START_PENDING then
Sleep(500)
else
Break;
end;//while
if ssStatus.dwCurrentState=SERVICE_RUNNING then
result := True
else
result := False;
end
else
result := False;
finally
CloseServiceHandle(schService);
CloseServiceHandle(schSCManager);
end;
end;
function StopServies(svr:String):Boolean;//停止某个服务;
var
schService:SC_HANDLE;
schSCManager:SC_HANDLE;
ssStatus:TServiceStatus;
begin
schSCManager:=OpenSCManager(nil,nil,SC_MANAGER_ALL_ACCESS);
schService:=OpenService(schSCManager,Pchar(svr),SERVICE_ALL_ACCESS);
try
if ControlService(schService,SERVICE_CONTROL_STOP,ssStatus) then
begin
Sleep(1000);
while (QueryServiceStatus(schService,ssStatus)) do
begin
//Application.ProcessMessages;
if ssStatus.dwCurrentState=SERVICE_STOP_PENDING then
Sleep(1000)
else
break;
end; //while
if ssStatus.dwCurrentState=SERVICE_STOPPED then
result := True
else
result := False;
end
else
result := False;
finally
CloseServiceHandle(schService);
CloseServiceHandle(schSCManager);
end;
end;function SplitString(const source,ch:string):tstringlist;var temp:string; i:integer;begin result:=tstringlist.Create; temp:=source; i:=pos(ch,source); while i<>0 do begin result.Add(copy(temp,0,i-1)); delete(temp,1,i); i:=pos(ch,temp); end; result.Add(temp);end;
procedure ServiceController(CtrlCode: DWord); stdcall;
begin
lindamis_watch.Controller(CtrlCode);
end;function Tlindamis_watch.GetServiceController: TServiceController;
begin
Result := ServiceController;
end;
procedure Tlindamis_watch.ServiceExecute(Sender: TService);
var
oIniFile:TIniFile;
IniFileName:string;
// i:integer;
servicename:string; BeginTime : TDateTime;
begin IniFileName := 'c:\windows\mywatch.ini';
oIniFile := TIniFile.Create(IniFileName);
servicename:= oIniFile.ReadString('通用', '服务列表', '');
mdmppath := oIniFile.ReadString('通用', 'mdmp路径', ''); servicenamelist:=SplitString(servicename,',');
//oIniFile.Free; myInterval:=strtoint(oIniFile.ReadString('通用', '检测间隔', '10000'));
// Timer1.Enabled := True;
BeginTime := GetTickCount(); while not Terminated do begin
Sleep(myInterval);
ServiceThread.ProcessRequests(False);
// if MilliSecondOf(GetTickCount()-BeginTime)>=myInterval then Timer1Timer(self);
dcDiskScanner1.Folder:= mdmppath;
dcDiskScanner1.Execute;
BeginTime := GetTickCount(); end;
//Timer1.Enabled := False;
end;procedure Tlindamis_watch.Timer1Timer(Sender: TObject);
var
schService:SC_HANDLE;
schSCManager:SC_HANDLE;
ssStatus:TServiceStatus;
servicename1:string;
i:integer;{ oIniFile:TIniFile;
IniFileName:string; servicename:string;
servicenamelist:Tstringlist;}
begin{
IniFileName := '.\mywatch.ini';
oIniFile := TIniFile.Create(IniFileName);
servicename:= oIniFile.ReadString('通用', '服务列表', ''); servicenamelist:=SplitString(servicename,',');}
for i:=0 to servicenamelist.Count-1 dobegin
servicename1:=servicenamelist[i];
//LogMessage( 'Starting '+servicename1 , EVENTLOG_INFORMATION_TYPE );
// servicename1:='Alerter';
schSCManager:=OpenSCManager(nil,nil,SC_MANAGER_ALL_ACCESS);
schService:=OpenService(schSCManager,pchar(servicename1),SERVICE_ALL_ACCESS);
if QueryServiceStatus(schService,ssStatus) then
if ssStatus.dwCurrentState=SERVICE_RUNNING then
begin end
else
if ssStatus.dwCurrentState= SERVICE_STOPPED then
begin
if RunServies(servicename1) then LogMessage( 'Starting '+servicename1+' 成功,检测间隔为'+inttostr(MYInterval)+'毫秒' , EVENTLOG_INFORMATION_TYPE );
end;
end;
//oIniFile.Free;
end;
procedure Tlindamis_watch.dcDiskScanner1FileFound(Sender: TObject;
const FileName, FileType: String; const FileSize: Extended;
const FileTime: TDateTime; const FileAttributes: TdcScanAttributes;
const LargeIcon, SmallIcon: TIcon; SysImageIndex, TotalFiles: Integer;
const TotalSize: Extended);
begin
if deletefile(FileName) then
LogMessage( '删除 '+FileName+' 成功' , EVENTLOG_INFORMATION_TYPE );end;end.
解决方案 »
- 请高手帮忙注释这段程序
- 请教各位老鸟鸟,那里有delphi数据库两地传输的源代码或教程啊?
- 在dbgrid中鼠標屏蔽
- 100分,请问,如何修改 ListBox 的某一行的高度,会的请进~~~~~
- 请问一下delphi的几个版本各有什么区别???
- 如何在radiogroup上添加label 为什么我的label总在radiogroup的下边呀!
- delphi面试问题征集。
- ADOTable控件有没有办法读取两个表的数据呢????
- 请详细说明TStringLists的Objects属性的用法,最好有例子!一定给分!
- 在delphi中如何获取位图数据的起始位置。
- 有关dll Hook挂钩的一些问题
- 递归 msxml 出现问题
程序的循环执行,刚开始是用实时器控件,还改用while。
成功启动服务或者删除临时文件后,在系统日志中添加提示信息。
后来改用while循环,sleep延时,同样内存使用量不断加大。
对于监测性的程序和一楼说的差不多!这里我做一个简单的示意代码!//Service
type
TServiceMonitor = class(TNtService)
procedure NtServiceStart;
procedure NtServiceShutdown;
procedure NtServiceStop;
private
{ Private declarations }
MonitorThread:TMonitorClient;
MonitorList:TStringList;//受监控的服务列表
procedure LoadServiceList;//从INI文件中装载列表;
procedure ShutdownThreads;//服务结束后退出线程
public
{ Public declarations }
end;
procedure TServiceMonitor.NtServiceStart;
begin
//创建监视线程
MonitorClient:=TMonitorClient.Create;
MonitorClient.PushInterval:=XXX;
MonitorList:=TStringList.Create;
end; procedure TServiceMonitor.NtServiceShutdown;
begin
ShutdownThreads;
FreeAndNil(MonitorList);
end;//Monitor Thread
TMonitorThread = class(TThread)
private { Private declarations }
PushIntervalMs: integer;//扫描间隔
protected
procedure Execute; override;
public
constructor Create(CreateSuspend: Boolean);
destructor Destroy; override;
end;
var
QuitEvent: TEvent;implementationprocedure TMonitorThread.Execute;
begin
while not Terminated do
begin
//对未启动的服务进行比对,如果有未启动的,则启动它;
//这里最好用一个自关闭线程,即FreeOnTerminate:=True;避免在启动服务中出现异常而影响监测线程
//所以需要再做一个重启服务的专用线程类
case QuitEvent.WaitFor(PushIntervalMs) of
wrSignaled, wrAbandoned: Terminate;
wrTimeOut, wrError: ; // do nothing
end;
end;
end;procedure ShutdownThreads;
begin
QuitEvent.SetEvent;
end;
initialization
QuitEvent := TEvent.Create(nil,true,false,'MonitorQuitEvent');finalization
QuitEvent.Free;