用delphi写了一个PC软件,能正常运行。现在想加入以服务方式启动,请问一下各位,如何实现服务启动呢,最好贴代码

解决方案 »

  1.   

    服务与桌面交互功能只有win 2k、xp、 server2003可以,之前的Windows NT、之后的Vista+都不支持,常规做法是服务启动一个单独的带界面程序,用CreateProcessAsUser之类的
      

  2.   

    参考:https://docs.microsoft.com/zh-cn/windows/desktop/Services/interactive-services
      

  3.   

    /// 这是线程单元/////////////////////////////////////
    unit WorkerThreadU;interfaceuses
      System.Classes;type
      TWorkerThread = class(TThread)
      private
        FPaused: Boolean;  protected
        procedure Execute; override;
      public
        procedure Pause;
        procedure Continue;
      end;implementationuses
      System.SysUtils, System.ioutils;procedure TWorkerThread.Continue;
    begin
      FPaused := False;
    end;procedure TWorkerThread.Execute;
    var
      ExePath, LogFileName: string;
      Log: TStreamWriter;
    begin
      try
        FPaused := False;
        ExePath := TPath.GetDirectoryName(GetModuleName(HInstance));
        LogFileName := TPath.Combine(ExePath,
          ClassName + '_' + IntToStr(CurrentThread.ThreadID) + '.txt');
        Log := TStreamWriter.Create(TFileStream.Create(LogFileName, fmCreate or fmShareDenyWrite));
        try
          while not Terminated do
          begin
            if not FPaused then
            begin
              Log.WriteLine('Message from thread: ' + TimeToStr(now));
            end;
            TThread.Sleep(1000);
          end;
        finally
          Log.Free;
        end;
      except
        on E: Exception do
        begin
          TFile.WriteAllText(TPath.Combine(ExePath, 'CRASH_LOG.TXT'), E.ClassName + ' ' + E.Message);
        end
      end;
    end;procedure TWorkerThread.Pause;
    begin
      FPaused := True;
    end;end.///////////////////以下是服务单元///////////////////////////////////
    unit ServiceU;interfaceuses
      Winapi.Windows, Winapi.Messages, System.SysUtils, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.SvcMgr, Vcl.Dialogs,
      WorkerThreadU;type
      TSampleService = class(TService)
        procedure ServiceExecute(Sender: TService);
        procedure ServiceStart(Sender: TService; var Started: Boolean);
        procedure ServiceStop(Sender: TService; var Stopped: Boolean);
        procedure ServicePause(Sender: TService; var Paused: Boolean);
        procedure ServiceContinue(Sender: TService; var Continued: Boolean);
        procedure ServiceAfterInstall(Sender: TService);
      private
        FWorkerThread: TWorkerThread;
        { Private declarations }
      public
        function GetServiceController: TServiceController; override;
        { Public declarations }
      end;{$R *.dfm}
    var
      SampleService: TSampleService;implementationuses
      System.Win.Registry;procedure ServiceController(CtrlCode: DWord); stdcall;
    begin
      SampleService.Controller(CtrlCode);
    end;function TSampleService.GetServiceController: TServiceController;
    begin
      Result := ServiceController;
    end;procedure TSampleService.ServiceAfterInstall(Sender: TService);
    var
      Reg: TRegistry;
    begin
      Reg := TRegistry.Create(KEY_READ or KEY_WRITE);
      try
        Reg.RootKey := HKEY_LOCAL_MACHINE;
        if Reg.OpenKey('\SYSTEM\CurrentControlSet\Services\' + name, false) then
        begin
          Reg.WriteString('Description', 'My Fantastic Windows Service');
          Reg.CloseKey;
        end;
      finally
        Reg.Free;
      end;
    end;procedure TSampleService.ServiceContinue(Sender: TService;
      var Continued: Boolean);
    begin
      FWorkerThread.Continue;
      Continued := True;
    end;procedure TSampleService.ServicePause(Sender: TService; var Paused: Boolean);
    begin
      FWorkerThread.Pause;
      Paused := True;
    end;procedure TSampleService.ServiceStart(Sender: TService; var Started: Boolean);
    begin
      FWorkerThread := TWorkerThread.Create(True);
      FWorkerThread.Start;
      Started := True;
    end;procedure TSampleService.ServiceStop(Sender: TService; var Stopped: Boolean);
    begin
      FWorkerThread.Terminate;
      FWorkerThread.WaitFor;
      FreeAndNil(FWorkerThread);
      Stopped := True;
    end;procedure TSampleService.ServiceExecute(Sender: TService);
    begin
      while not Terminated do
      begin
        ServiceThread.ProcessRequests(false);
        TThread.Sleep(1000);
      end;
    end;end.
    /////////////////以下是使用方法//////////////////
    进 入系统命令行模式
    切换到服务可执行文件夹下,C:\<ExeProjectPath>\WindowsService.exe /install   进行安装,成功后到服务窗口找到‘My Sample Service’,启用。然后在C:\<ExeProjectPath>文件夹有可以看到‘TWorkerThread‘’log文件,共有两个!