也可以作为windows服务安装的独立Delphi应用程序

也可以作为windows服务安装的独立Delphi应用程序,windows,delphi,windows-services,Windows,Delphi,Windows Services,在Delphi中,您可以创建一个独立的Windows VCL表单应用程序。您还可以创建Windows服务应用程序 是否可以将两者结合在一个可以作为独立应用程序运行,也可以作为Windows服务安装的应用程序中?这是可能的,但在这种情况下,您不能使用普通的TServiceApplication和TService。您应该自己实现所有特定于服务的代码 我们遇到了一个类似的问题,并制作了两个框架应用程序:一个用于sand单独的exe,另一个用于服务。现在我们可以创建一个嵌入在两个容器中的BPL/DLL

在Delphi中,您可以创建一个独立的Windows VCL表单应用程序。您还可以创建Windows服务应用程序


是否可以将两者结合在一个可以作为独立应用程序运行,也可以作为Windows服务安装的应用程序中?

这是可能的,但在这种情况下,您不能使用普通的TServiceApplication和TService。您应该自己实现所有特定于服务的代码

我们遇到了一个类似的问题,并制作了两个框架应用程序:一个用于sand单独的exe,另一个用于服务。现在我们可以创建一个嵌入在两个容器中的BPL/DLL


如果你想花钱:你应该看看SvCOM,我认为他们有解决问题的办法。

完全可能。诀窍是编辑.dpr,以便在希望作为应用程序运行时创建主窗体,在希望作为服务运行时创建服务窗体。像这样:

if SvComFindCommand('config') then begin
  //When run with the /config switch, display the configuration dialog.
  Forms.Application.Initialize;
  Forms.Application.CreateForm(TfrmConfig, frmConfig);
  Forms.Application.Run;
end
else begin
  SvCom_NTService.Application.Initialize;
  SvCom_NTService.Application.CreateForm(TscmServiceSvc, scmServiceSvc);
  SvCom_NTService.Application.Run;
end;
上面的代码使用SvCom来运行服务,但是使用标准的TService可以实现完全相同的效果


很多年前,我为德尔福杂志写了一篇关于这方面的文章。你可以在这里读到:。

这很难解释,但我会尽力:)

我已经在我的项目中这样做了(Delphi 5):

程序TestSvc;
使用SvcMgr,
SvcMain,//从TService继承的TsetService的单元
...
;
变量
IsDesktopMode:布尔型;
函数IsServiceRunning:布尔值;
变量
Svc:整数;
SvcMgr:整数;
ServSt:TServiceStatus;
开始
结果:=假;
SvcMgr:=OpenSCManager(nil,nil,SC\u MANAGER\u CONNECT);
如果SvcMgr=0,则退出;
尝试
Svc:=OpenService(SvcMgr,'TestService',SERVICE\u QUERY\u STATUS);
如果Svc=0,则退出;
尝试
如果没有查询服务状态(Svc、ServSt),则退出;
结果:=(ServSt.dwCurrentState=SERVICE\u RUNNING)或(ServSt.dwCurrentState=SERVICE\u START\u PENDING);
最后
关闭服务手柄(Svc);
结束;
最后
CloseServiceHandle(SvcMgr);
结束;
结束;
开始
如果(WIN32 PLATFORM VER_PLATFORM_WIN32_NT)或FindCmdLineSwitch('S',['-','/'],True),则
IsDesktopMode:=真
否则开始
IsDesktopMode:=非FindCmdLineSwitch('INSTALL',['-','/'],True)和
非FindCmdLineSwitch('UNINSTALL'、['-'、'/']、True)和
不令人担忧;
结束;
如果是IsDesktopMode,则开始//桌面模式
Forms.Application.Initialize;
Forms.Application.Title:='应用程序。标题';
ShowTrayIcon(Forms.Application.Icon.Handle,NIM_ADD);//此功能用于创建图标到任务栏。您可以为图标创建弹出菜单。
当GetMessage(消息,0,0,0)开始时
翻译信息;
发送消息(Msg);
结束;
ShowTrayIcon(Forms.Application.Icon.Handle,NIM_DELETE);//用于删除托盘图标
结束或开始//服务模式
SvcMgr.Application.Initialize;
SvcMgr.Application.CreateForm(TTestService,TestService);
SvcMgr.Application.Run;
结束;
结束。

这个问题有一个解决方案,不需要编写一行代码。这在一定程度上取决于您的应用程序,但通常是可以实现的。试试这个:。在将应用程序作为服务启动之前,不要忘记启动应用程序依赖的所有服务。谷歌搜索如何做到这一点的信息。

另一个几乎更简单的选择是在,您只需要包括一个单元,并将您的DPR更改为:

begin
  if CiaStartService('SERVICE NAME') then begin
    CiaService.CreateForm(TMain, Main);
    CiaService.Run;
    Exit;
  end;

  Application.Initialize;
  Application.Title := 'SERVICE NAME';
  Application.CreateForm(TMain, Main);
  Application.Run;
end.

虽然这个示例现在已经过时,但该技术非常简单,即使使用Delphi XE2,它仍然可以工作。有了这个选项,您的应用程序将继续作为非服务运行,直到您使用“/install”参数(在提升的命令提示符下)。之后,它将作为服务运行,直到您使用“/uninstall”参数(也在提升的命令提示符上)。

是否可以创建一个
{$DEFINE}
全局编译来标识它是在单机模式还是windows服务模式下运行?
begin
  if CiaStartService('SERVICE NAME') then begin
    CiaService.CreateForm(TMain, Main);
    CiaService.Run;
    Exit;
  end;

  Application.Initialize;
  Application.Title := 'SERVICE NAME';
  Application.CreateForm(TMain, Main);
  Application.Run;
end.