Database Delphi中带数据库连接的Windows服务
我只是想了解一下情况 我创建了一个Windows服务,用于管理我的应用程序的任务 服务连接到数据库(Firebird)并调用执行任务管理的组件。 该过程工作正常,但在Windows 10中,该服务不会在计算机重新启动后自动启动。在其他版本的Windows中,一切都能完美运行。在测试中,我发现如果我对调用任务执行的方法进行注释,服务通常会在Windows 10上启动Database Delphi中带数据库连接的Windows服务,database,windows,delphi,service,firebird,Database,Windows,Delphi,Service,Firebird,我只是想了解一下情况 我创建了一个Windows服务,用于管理我的应用程序的任务 服务连接到数据库(Firebird)并调用执行任务管理的组件。 该过程工作正常,但在Windows 10中,该服务不会在计算机重新启动后自动启动。在其他版本的Windows中,一切都能完美运行。在测试中,我发现如果我对调用任务执行的方法进行注释,服务通常会在Windows 10上启动 Procedure TDmTaskService.ServiceExecute(Sender: TService); Begin
Procedure TDmTaskService.ServiceExecute(Sender: TService);
Begin
Inherited;
While Not Terminated Do
Begin
//Process;
Sleep(3000);
ServiceThread.ProcessRequests(False);
End;
End;
问题是在组件或服务中没有生成任何异常
通过分析Windows事件监视器,我发现我的服务出现的错误是超时,在这种情况下,服务无法在时间限制内连接到服务管理器。不再生成任何异常
有人知道用Delphi制作的连接到数据库的Windows服务吗?
我的源代码示例:
**Base class:**
unit UnTaskServiceDmBase;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, SvcMgr, Dialogs;
type
TDmTaskServicosBase = class(TService)
private
{ Private declarations }
public
function GetServiceController: TServiceController; override;
{ Public declarations }
end;
var
DmTaskServiceBase: TDmTaskServicosBase;
implementation
{$R *.DFM}
procedure ServiceController(CtrlCode: DWord); stdcall;
begin
DmJBServicosBase.Controller(CtrlCode);
end;
function TDmTaskServicosBase.GetServiceController: TServiceController;
begin
Result := ServiceController;
end;
end.
**Service Class:**
Unit UnTaskServiceDm;
Interface
Uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, SvcMgr, Dialogs,
UnJBTask,
UnJBReturnTypes,
UnJBUtilsFilesLog,
UnTaskServiceDmConfig,
UnTaskServiceDmConnection,
ExtCtrls,
IniFiles;
Type
TDmTaskService = Class(TDmTaskServicosBase)
Procedure ServiceExecute(Sender: TService);
Procedure ServiceCreate(Sender: TObject);
Procedure ServiceStop(Sender: TService; Var Stopped: Boolean);
Private
FTaskServiceConfig: TDmTaskServiceConfig;
FStatus: TResultStatus;
FDmConnection: TDmTaskServiceConnection;
FJBTask: TJBTask;
FLog: TJBUtilsFilesLog;
Procedure ExecuteTasksSchedule;
Procedure UpdateServiceInformation;
Procedure Process;
Procedure UpdateConnection;
Public
Function GetServiceController: TServiceController; Override;
End;
Implementation
{$R *.DFM}
Procedure ServiceController(CtrlCode: DWord); Stdcall;
Begin
DmTaskService.Controller(CtrlCode);
End;
Procedure TDmTaskService.UpdateConnection;
Begin
Try
FDmConnection.SqcCon.Connected := False;
FDmConnection.SqcCon.Connected := True;
FLog.Adicionar('Conexão com banco restabelecida.');
FLog.FinalizarLog;
Except
On E: Exception Do
Begin
FLog.Adicionar('Erro ao restabelecer conexão com o banco de dados.' +
sLineBreak + sLineBreak + E.Message);
FLog.FinalizarLog;
End;
End;
End;
Procedure TDmTaskService.UpdateServiceInformation;
Begin
Inherited;
Try
Try
FTaskServiceConfig.Load;
FLog.Adicionar('Dados registro serviço.');
FLog.Adicionar('Nome: ' + FTaskServiceConfig.ServiceName);
FLog.Adicionar('Descrição: ' + FTaskServiceConfig.ServiceDescription);
If (FTaskServiceConfig.ServiceName <> EmptyStr) And
(FTaskServiceConfig.ServiceDescription <> EmptyStr) Then
Begin
Name := FTaskServiceConfig.ServiceName ;
DisplayName := FTaskServiceConfig.ServiceDescription;
End;
FTaskServiceConfig.Close;
Except
On E: Exception Do
Begin
FLog.Adicionar('Erro adicionar dados registro serviço.');
FLog.Adicionar('Erro ocorrido: ' + sLineBreak + sLineBreak + E.Message);
End;
End;
Finally
FLog.Adicionar('Name: ' + Name);
FLog.Adicionar('DisplayName: ' + DisplayName);
FLog.FinalizarLog;
End;
End;
Procedure TDmTaskService.Process;
Begin
Try
If FDmConnection.SqcCon.Connected Then
Begin
ExecuteTasksSchedule;
End
Else
UpdateConnection;
Except
On E: Exception Do
Begin
FLog.Adicionar('Ocorreu um erro ao checar as tarefas.' + sLineBreak +
'Erro ocorrido: ' + sLineBreak + E.Message);
FLog.FinalizarLog;
UpdateConnection;
End;
End;
End;
Procedure TDmTaskService.ExecutarTarefasAgendadas;
Begin
If FJBTask.ExistTaskDelayed Then
Begin
Try
FJBTask.ExecuteTasks;
Except
On E: Exception Do
Begin
FLog.Adicionar('Ocorreu um erro ao executar as tarefas agendadas.' +
sLineBreak + 'Erro ocorrido: ' + sLineBreak + E.Message);
FLog.FinalizarLog;
UpdateConnection;
End;
End;
End;
End;
Function TDmTaskService.GetServiceController: TServiceController;
Begin
Result := ServiceController;
End;
Procedure TDmTaskService.ServiceCreate(Sender: TObject);
Begin
Inherited;
Try
FLog := TJBUtilsFilesLog.Create;
FLog.ArquivoLog := IncludeTrailingPathDelimiter(FLog.LogFolder) + 'TaksService.log';
FDmConnection := TDmTaskServiceConexao.Create(Self);
FDmConnection.Log := FLog;
FJBTask := TJBTarefa.Create(Self);
FJBTask.SQLConnection := FDmConnection.SqcConexao;
FTaskServiceConfig := TDmTaskServiceConfig.Create(Self);
FTaskServiceConfig.SQLConnection := FDmConnection.SqcConexao;
FStatus := FDmConnection.ConfigurouConexao;
If FStatus.ResultValue Then
Begin
UpdateServiceInformation;
End
Else
Begin
FLog.Adicionar(FStatus.MessageOut);
FLog.FinalizarLog;
End;
Except
On E: Exception Do
Begin
FLog.Adicionar('Não foi possível iniciar o serviço.' + sLineBreak +
'Erro ocorrido: ' + sLineBreak + sLineBreak + E.Message);
FLog.FinalizarLog;
Abort;
End;
End;
End;
Procedure TDmTaskService.ServiceExecute(Sender: TService);
Begin
Inherited;
While Not Terminated Do
Begin
Process;
Sleep(3000);
ServiceThread.ProcessRequests(False);
End;
End;
Procedure TDmTaskService.ServiceStop(Sender: TService; Var Stopped: Boolean);
Begin
Inherited;
If Assigned(FDmConnection) Then
Begin
FLog.Adicionar('Finalizando serviço.');
FLog.Adicionar('Fechando conexão.');
Try
FDmConnection.SqcConexao.Close;
Finally
FLog.FinalizarLog;
End;
End;
End;
End.
Procedure TForm3.JBButton3Click(Sender: TObject);
Const
CKeyConfigTimeout = 'SYSTEM\CurrentControlSet\Control';
CValueConfigTimeout = 'ServicesPipeTimeout';
Var
LReg: TRegistry;
Begin
LReg := TRegistry.Create;
Try
LReg.RootKey := HKEY_LOCAL_MACHINE;
LReg.OpenKey(CKeyConfigTimeout, False);
LReg.WriteInteger(CValueConfigTimeout, 120000);
Finally
LReg.CloseKey;
FreeAndNil(LReg);
End;
End;
**基类:**
单位服务基地;
接口
使用
窗口、消息、系统、类、图形、控件、SvcMgr、对话框;
类型
TDmTaskServicosBase=类(TService)
私有的
{私有声明}
公众的
函数GetServiceController:TServiceController;推翻
{公开声明}
结束;
变量
DmTaskServiceBase:tdmtaskservicebase;
实施
{$R*.DFM}
程序服务控制员(CtrlCode:DWord);stdcall;
开始
DmJBServicosBase.Controller(CtrlCode);
结束;
函数tdmtaskservicebase.GetServiceController:TServiceController;
开始
结果:=服务控制器;
结束;
结束。
**服务类别:**
服务单位DM;
接口
使用
窗口、消息、系统工具、类、图形、控件、SvcMgr、对话框、,
联合国养恤基金任务,
不合适的类型,
不公正的文件记录,
UntaskServicedConfig,
UntaskServicedConnection,
ExtCtrls,
INI文件;
类型
TDmTaskService=Class(TDMTaskServicoBase)
过程ServiceExecute(发送方:TService);
过程服务创建(发送方:TObject);
过程ServiceStop(发送方:TService;停止变量:Boolean);
私有的
ftasksserviceconfig:tdmtasksserviceconfig;
FStatus:TResultStatus;
FDmConnection:tdmtasksserviceconnection;
FJBTask:TJBTask;
FLog:TJBUtilsFilesLog;
程序执行任务时间表;
程序更新服务信息;
程序过程;
程序更新连接;
公开的
函数GetServiceController:TServiceController;推翻
结束;
实施
{$R*.DFM}
程序服务控制员(CtrlCode:DWord);Stdcall;
开始
DmTaskService.Controller(CtrlCode);
结束;
程序TDmTaskService.UpdateConnection;
开始
尝试
FDmConnection.SqcCon.Connected:=False;
FDmConnection.SqcCon.Connected:=True;
弗洛格·阿迪西奥纳尔(Conexão com banco restabelecida.);
FLog.ARLOG;
除了
关于E:Exception-Do
开始
弗洛格·阿迪西奥纳尔(Erro ao restabelecer conexão com o banco de dados)+
sLineBreak+sLineBreak+E.Message);
FLog.ARLOG;
结束;
结束;
结束;
程序TDmTaskService.UpdateServiceInformation;
开始
继承;
尝试
尝试
ftasksserviceconfig.Load;
弗洛格·阿迪西奥纳(Dados registro serviço.);
FLog.Adicionar('Nome:'+ftasksserviceconfig.ServiceName);
FLog.Adicionar('descripão:'+ftasksserviceconfig.servicesdescription);
如果(ftasksserviceconfig.ServiceName EmptyStr)和
(ftasksserviceconfig.servicescription EmptyStr)然后
开始
名称:=ftasksserviceconfig.ServiceName;
DisplayName:=FTaskServiceConfig.ServiceDescription;
结束;
ftasksserviceconfig.Close;
除了
关于E:Exception-Do
开始
弗洛格·阿迪西奥纳尔(Erro-Adicionar dados registro serviço.);
FLog.Adicionar('Erro ocorrido:'+sLineBreak+sLineBreak+E.Message);
结束;
结束;
最后
FLog.Adicionar('名称:'+名称);
FLog.Adicionar('DisplayName:'+DisplayName);
FLog.ARLOG;
结束;
结束;
程序TDmTaskService.Process;
开始
尝试
如果FDmConnection.SqcCon.Connected,则
开始
执行任务时间表;
终点
其他的
更新连接;
除了
关于E:Exception-Do
开始
鞭笞阿迪西奥纳尔('Ocorreu um erro ao checar as tarefas.'+sLineBreak+
“Erro ocorrido:”+sLineBreak+E.Message);
FLog.ARLOG;
更新连接;
结束;
结束;
结束;
程序tdmtasksservice.executartarafasagendadas;
开始
如果FJBTask.ExistTaskDelayed,则
开始
尝试
FJBTask.ExecuteTasks;
除了
关于E:Exception-Do
开始
鞭笞Adicionar(“作为代理的执行者的错误。”+
sLineBreak+“Erro ocorrido:”+sLineBreak+E.Message);
FLog.ARLOG;
更新连接;
结束;
结束;
结束;
结束;
函数TDmTaskService.GetServiceController:TServiceController;
开始
结果:=服务控制器;
结束;
过程TDmTaskService.ServiceCreate(发件人:ToObject);
开始
继承;
尝试
FLog:=TJBUtilsFilesLog.Create;
FLog.ArquivoLog:=IncludeTrailingPathDelimiter(FLog.LogFolder)+“TaksService.log”;
FDmConnection:=tdmtasksserviceconexao.Create(Self);
FDmConnection.Log:=FLog;
FJBTask:=TJBTarefa.Create(Self);
FJBTask.SQLConnection:=FDmConnection.SqcConexao;
FTaskServi
Procedure TForm3.JBButton3Click(Sender: TObject);
Const
CKeyConfigTimeout = 'SYSTEM\CurrentControlSet\Control';
CValueConfigTimeout = 'ServicesPipeTimeout';
Var
LReg: TRegistry;
Begin
LReg := TRegistry.Create;
Try
LReg.RootKey := HKEY_LOCAL_MACHINE;
LReg.OpenKey(CKeyConfigTimeout, False);
LReg.WriteInteger(CValueConfigTimeout, 120000);
Finally
LReg.CloseKey;
FreeAndNil(LReg);
End;
End;