Delphi Windows服务设计

Delphi Windows服务设计,第1张

概述Delphi Windows服务设计 我从来没有创建过Windows服务,但一直在阅读我发现的一切。我所遇到的所有文章或例子在实施过程中都非常基础,范围有限。没有看到任何超越这一点或解决具体情况的事情。所以,我有我可能会找到的所有理论,现在我准备好深入这个项目。我喜欢布置我的想法,并得到一些关于人们的想法的反馈。我将从应用程序中描述我需​​要的内容,以及我打算如何构建它。我会感谢任何有建立Wind Delphi windows服务设计

我从来没有创建过windows服务,但一直在阅读我发现的一切。我所遇到的所有文章或例子在实施过程中都非常基础,范围有限。没有看到任何超越这一点或解决具体情况的事情。所以,我有我可能会找到的所有理论,现在我准备好深入这个项目。我喜欢布置我的想法,并得到一些关于人们的想法的反馈。我将从应用程序中描述我需​​要的内容,以及我打算如何构建它。我会感谢任何有建立windows服务经验的人的意见,以及他们愿意分享的任何建议。

[SCENARIO]
现在我有一个应用程序(我将这个UPDATEAPPliCATION)提供给我们所有其他应用程序的更新。为了运行我们的任何应用程序,您首先必须运行此UPDATEAPPliCATION程序并传递所需应用程序的参数。 UPDATEAPPliCATION调用一个WebService,返回关于所需应用程序是否有任何更新的XML信息。

如果有更新,UPDATEAPPliCATION将以EXE或ZIP格式下载更新,并替换相应的文件来更新目标应用程序。之后,UPDATEAPPliCATION执行ShellExecute启动所需的应用程序,然后UPDATEAPPliCATION关闭。

这是一个相当基本的过程,多年来一直运作良好。 UPDATEAPPliCATION程序是Delphi应用程序,我们的其他应用程序是混合的:Delphi,VB6,MS Access,.NET。

[问题]
随着Vista和windows 7的转移,安全性发生了巨大变化。由于UPDATEAPPliCATION的性质,UAC将不允许应用程序在没有admin acces或UAC完全关闭的情况下运行。我们正在将许多应用程序升级到.NET,在此过程中,我希望应用程序以及UPDATEAPPliCATION符合UAC标准。从我研究过的唯一方法是通过创建UPDATEAPPliCATION作为windows服务。因此,本质上,我需要将UPDATEAPPliCATION的功能复制到windows服务体系结构中。

[我的设计]
我使用的是DelphiXE2。我的设计将由3部分组成一个单一的解决方案:windows服务,小托盘应用程序与windows服务交互,以及我重新设计的应用程序将发送消息到windows服务。

>我的windows服务(我将称之为UPDATESERVICE)将作为windows服务运行,并创建一个TCP服务器来侦听请求。
>托盘应用程序(我将称之为TRAYAPP)将使用TCP ClIEnt配置/管理UPDATESERVICE。
>我的USERAPPliCATION在启动时将向UPDATESERVICE发送一条TCP消息,表示“此应用程序”已启动。

[UPDATESERVICE]
将收听消息。如果收到USERAPPliCATION已经启动的消息,它会调用Web服务来查看是否有更新。如果有,将通知用户关闭应用程序,并允许UPDATESERVICE更新应用程序。 UPDATESERVICE将下载相应的文件并更新应用程序。

现在我已经解释了我正在做什么的基础知识,可以问我需要回答的具体问题。这些都与我应该如何构建我的windows服务有关。我也打算使用OmniThread进行线程管理。

当我的服务启动时,我需要创建TCP服务器。

> TCP服务应该在自己的线程上创建吗?
>如果TCP服务是自己的线程,我该如何保持线程活着?否则,我可以启动TCP服务,但我不知道在TCP服务单元中将使用什么代码来保持线程运行?
> windows Services事件应该创建TCP服务? OnExecute?的OnStart?在OnCreate?毕竟我读过它不清楚应该使用什么事件。
>当TCP服务收到消息以执行某些 *** 作时,应该在TCP Service线程内执行工作,还是从主UPDATESERVICE产生新线程?例如:

>如果TCP服务获得一条消息来检查使用http的更新,则TCP服务线程会产生一个新线程来完成此工作
>或者,如果TCP服务线程向UPDATESERVICE发送一条消息,以产生一个新线程来完成此工作
>甚至有关系吗?

>是否可以在Delphi代码中启动/停止/注册/注销windows服务?

这是我所有的问题。这可能不是一个正确/错误的答案,而只是基于经验的偏好。如果您使用Delphi构建服务,您可能有一些我会发现有用的输入。如果你有一个更强大的项目,那么一个基本的“开始一个服务和睡眠”,并愿意分享它 – 即使我没有运行或只是伪装的代码 – 我相信这将是无价的。感谢您阅读我长久以来的问题。如果你能想到一个更好的方法来分享你的想法。我将补充说,我们的几个应用程序可以由公众下载和运行,所以我没有完全控制预期的环境。任何建议/意见/帮助将不胜感激。

解决方法 快速答案:

1& 3)是的。根据经验,不要实现OnExecute服务事件。从OnStart服务事件中生成自己的线程。当您收到OnStop服务事件时,线程可以被终止。

2)你保持你的线程如此(执行方法):

while not Terminated dobegin  // do somethingend;

4)通常每个客户端连接都将自己生成线程。 (即TCP服务器为每个客户端生成一个新线程)。使用一个众所周知的堆栈,如Indy或ICS。关于http更新,您可以在生成的客户端连接线程中执行此 *** 作。

5)是的,请注意,您需要提高这样做的权限。

我在职业生涯中已经做了不少服务,到现在为止,我总是使用同样的服务方式的骨架:

unit u_svc_main;interfaceuses  // 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.
总结

以上是内存溢出为你收集整理的Delphi Windows服务设计全部内容,希望文章能够帮你解决Delphi Windows服务设计所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1280829.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-09
下一篇 2022-06-09

发表评论

登录后才能评论

评论列表(0条)

保存