Database Delphi中带数据库连接的Windows服务

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

我只是想了解一下情况

我创建了一个Windows服务,用于管理我的应用程序的任务

服务连接到数据库(Firebird)并调用执行任务管理的组件。

该过程工作正常,但在Windows 10中,该服务不会在计算机重新启动后自动启动。在其他版本的Windows中,一切都能完美运行。在测试中,我发现如果我对调用任务执行的方法进行注释,服务通常会在Windows 10上启动

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;