delphiwindows服务设计
delphiwindows服务设计 我从未创建过windows服务,但一直在阅读我找到的所有内容。我遇到的所有文章或示例在实现方面都非常基本,并且范围有限。还没有看到任何超出此范围或解决特定场景的内容。所以,我有可能找到的所有理论,现在我准备投入这个项目。我喜欢规划我的想法,并从人们的想法中得到一些反馈。我将描述我需要从应用程序中得到什么,以及我打算如何构建它。我非常感谢任何有构建windows服务经验的人的评论,以及他们愿意分享的任何建议 [场景] 现在我有一个应用程序(我称之为UPDATEAPPLICATION),它为所有其他应用程序提供更新。为了运行我们的任何应用程序,您首先必须运行此UPDATEAPPLICATION程序,并向其传递所需应用程序的参数。UPDATEAPPLICATION调用一个Web服务,该服务返回有关所需应用程序是否有任何更新的XML信息 如果有更新,UPDATEAPPLICATION将以EXE或ZIP格式下载更新,并替换相应的文件以更新目标应用程序。之后,UPDATEAPPLICATION执行ShellExecute以启动所需的应用程序,然后UPDATEAPPLICATION关闭 这是一个相当基本的过程,多年来一直运作良好。UPDATEAPPLICATION程序是一个Delphi应用程序,我们的其他应用程序是混合的:Delphi、VB6、MS Access、.NET [问题] 随着Vista和Windows7的出现,安全性发生了巨大的变化。由于UPDATEAPPLICATION的性质,UAC不允许应用程序在没有管理员访问或UAC完全关闭的情况下运行。我们正在将许多应用程序升级到.NET,在此过程中,我希望这些应用程序以及UPDATEAPPLICATION都符合UAC。根据我的研究,实现这一点的唯一方法是将UPDATEAPPLICATION创建为Windows服务。因此,本质上,我需要将UPDATEAPPLICATION的功能复制到Windows服务体系结构中 [我的设计] 我用的是DelphiXE2。我的设计将由3个部分组成一个单一的解决方案:一个Windows服务,一个与Windows服务交互的小托盘应用程序,以及我重新设计的将向Windows服务发送消息的应用程序delphiwindows服务设计,windows,delphi,service,tcp,Windows,Delphi,Service,Tcp,delphiwindows服务设计 我从未创建过windows服务,但一直在阅读我找到的所有内容。我遇到的所有文章或示例在实现方面都非常基本,并且范围有限。还没有看到任何超出此范围或解决特定场景的内容。所以,我有可能找到的所有理论,现在我准备投入这个项目。我喜欢规划我的想法,并从人们的想法中得到一些反馈。我将描述我需要从应用程序中得到什么,以及我打算如何构建它。我非常感谢任何有构建windows服务经验的人的评论,以及他们愿意分享的任何建议 [场景] 现在我有一个应用程序(我称之为UPDATEA
- 如果TCP服务收到一条消息,要使用HTTP检查更新,TCP服务线程是否应该生成一个新线程来执行此工作
- 或者,TCP服务线程是否应该向UPDATESERVICE发送一条消息以生成一个新线程来执行此工作
- 这有关系吗
while not Terminated do
begin
// do something
end;
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.