Delphi Windows服务设计
Delphi Windows服务设计
我从来没有创建过Windows服务,但一直在阅读我发现的一切。我所遇到的所有文章或例子在实施过程中都非常基础,范围有限。没有看到任何超越这一点或解决具体情况的事情。所以,我有我可能会找到的所有理论,现在我准备好深入这个项目。我喜欢布置我的想法,并得到一些关于人们的想法的反馈。我将从应用程序中描述我需??要的内容,以及我打算如何构建它。我会感谢任何有建立Windows服务经验的人的意见,以及他们愿意分享的任何建议。 [SCENARIO] 如果有更新,UPDATEAPPLICATION将以EXE或ZIP格式下载更新,并替换相应的文件来更新目标应用程序。之后,UPDATEAPPLICATION执行ShellExecute启动所需的应用程序,然后UPDATEAPPLICATION关闭。 这是一个相当基本的过程,多年来一直运作良好。 UPDATEAPPLICATION程序是Delphi应用程序,我们的其他应用程序是混合的:Delphi,VB6,MS Access,.NET。 [问题] [我的设计] >我的Windows服务(我将称之为UPDATESERVICE)将作为Windows服务运行,并创建一个TCP服务器来侦听请求。 [UPDATESERVICE] 现在我已经解释了我正在做什么的基础知识,可以问我需要回答的具体问题。这些都与我应该如何构建我的Windows服务有关。我也打算使用OmniThread进行线程管理。 当我的服务启动时,我需要创建TCP服务器。 > TCP服务应该在自己的线程上创建吗? >如果TCP服务获得一条消息来检查使用HTTP的更新,则TCP服务线程会产生一个新线程来完成此工作 >是否可以在Delphi代码中启动/停止/注册/注销Windows服务? 这是我所有的问题。这可能不是一个正确/错误的答案,而只是基于经验的偏好。如果您使用Delphi构建服务,您可能有一些我会发现有用的输入。如果你有一个更强大的项目,那么一个基本的“开始一个服务和睡眠”,并愿意分享它 – 即使我没有运行或只是伪装的代码 – 我相信这将是无价的。感谢您阅读我长久以来的问题。如果你能想到一个更好的方法来分享你的想法。我将补充说,我们的几个应用程序可以由公众下载和运行,所以我没有完全控制预期的环境。任何建议/意见/帮助将不胜感激。 解决方法
快速答案:
1& 3)是的。根据经验,不要实现OnExecute服务事件。从OnStart服务事件中生成自己的线程。当您收到OnStop服务事件时,线程可以被终止。 2)你保持你的线程如此(执行方法): while not Terminated do begin // do something end; 4)通常每个客户端连接都将自己生成线程。 (即TCP服务器为每个客户端生成一个新线程)。使用一个众所周知的堆栈,如Indy或ICS。关于HTTP更新,您可以在生成的客户端连接线程中执行此操作。 5)是的,请注意,您需要提高这样做的权限。 我在职业生涯中已经做了不少服务,到现在为止,我总是使用同样的服务方式的骨架: unit u_svc_main; interface uses // Own units u_globals,u_eventlog,u_MyThread,// Third party units // Delphi units Windows,Messages,Registry,SysUtils,Classes,SvcMgr; type TMyService = class(TService) procedure ServiceCreate(Sender: TObject); procedure ServiceAfterUninstall(Sender: TService); procedure ServiceAfterInstall(Sender: TService); procedure ServiceShutdown(Sender: TService); procedure ServiceStop(Sender: TService; var Stopped: Boolean); procedure ServiceStart(Sender: TService; var Started: Boolean); private { Private declarations } MyThread : TMyThread; public { Public declarations } function GetServiceController: TServiceController; override; end; var MyService : TMyService; implementation {$R *.DFM} procedure ServiceController(CtrlCode: DWord); stdcall; begin MyService.Controller(CtrlCode); end; function TMyService.GetServiceController: TServiceController; begin Result := ServiceController; end; procedure TMyService.ServiceCreate(Sender: TObject); begin DisplayName := 'myservice'; end; procedure TMyService.ServiceAfterInstall(Sender: TService); var Reg : TRegistry; ImagePath : string; begin // create needed registry entries after service installation Reg := TRegistry.Create; try Reg.RootKey := HKEY_LOCAL_MACHINE; // set service description if Reg.OpenKey(STR_REGKEY_SVC,False) then begin ImagePath := Reg.ReadString(STR_REGVAL_IMAGEPATH); Reg.WriteString(STR_REGVAL_DESCRIPTION,STR_INFO_SVC_DESC); Reg.CloseKey; end; // set message resource for eventlog if Reg.OpenKey(STR_REGKEY_EVENTMSG,True) then begin Reg.WriteString(STR_REGVAL_EVENTMESSAGEFILE,ImagePath); Reg.WriteInteger(STR_REGVAL_TYPESSUPPORTED,7); Reg.CloseKey; end; // set installdir if ImagePath <> '' then if Reg.OpenKey(STR_REGKEY_FULL,True) then begin Reg.WriteString(STR_REGVAL_INSTALLDIR,ExtractFilePath(ImagePath)); Reg.CloseKey; end; finally FreeAndNil(Reg); end; end; procedure TMyService.ServiceAfterUninstall(Sender: TService); var Reg : TRegistry; begin Reg := TRegistry.Create; try // delete self created registry keys Reg.RootKey := HKEY_LOCAL_MACHINE; Reg.DeleteKey(STR_REGKEY_EVENTMSG); finally FreeAndNil(Reg); end; end; procedure TMyService.ServiceShutdown(Sender: TService); var Stopped : boolean; begin // is called when windows shuts down ServiceStop(Self,Stopped); end; procedure TMyService.ServiceStart(Sender: TService; var Started: Boolean); begin Started := False; try MyThread := TMyThread.Create; MyThread.Resume; NTEventLog.Add(Eventlog_Success,STR_INFO_SVC_STARTED); Started := True; except on E : Exception do begin // add event in eventlog with reason why the service couldn't start NTEventLog.Add(Eventlog_Error_Type,Format(STR_INFO_SVC_STARTFAIL,[E.Message])); end; end; end; procedure TMyService.ServiceStop(Sender: TService; var Stopped: Boolean); begin try Stopped := True; // always stop service,even if we had exceptions,this is to prevent "stuck" service (must reboot then) MyThread.Terminate; // give MyThread 60 seconds to terminate if WaitForSingleObject(MyThread.ThreadEvent,60000) = WAIT_OBJECT_0 then begin FreeAndNil(MyThread); NTEventLog.Add(Eventlog_Success,STR_INFO_SVC_STOPPED); end; except on E : Exception do begin // add event in eventlog with reason why the service couldn't stop NTEventLog.Add(Eventlog_Error_Type,Format(STR_INFO_SVC_STOPFAIL,[E.Message])); end; end; end; end. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |