A standalone Delphi application that can also be installed as windows service

In Delphi you can create a standalone Windows VCL Forms application. You can also create a Windows service application. Is it possible to combine the two in a single application that can run as a standalone application and can also be installed as a Windows service?

65.2k 30 30 gold badges 147 147 silver badges 241 241 bronze badges asked Mar 5, 2010 at 14:30 935 2 2 gold badges 14 14 silver badges 21 21 bronze badges

5 Answers 5

Totally possible. The trick is to edit the .dpr to create main form when you want to run as an application and the service form when you want to run as a service. Like this:

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; 

The code above uses SvCom to run the service but exactly the same effect could be achieved using the standard TService.

I wrote an article about that for The Delphi Magazine many years ago. You can read it here: Many Faces Of An Application.

answered Mar 5, 2010 at 15:19 26.8k 10 10 gold badges 78 78 silver badges 142 142 bronze badges

Is it possible to create a global compilation that identifies if it is running on standlone or windows service mode?

Commented Sep 15, 2015 at 18:24

It'll be hard to explain but I will try :)

I've done it in my project like that (Delphi 5):

program TestSvc; uses SvcMgr, SvcMain, //the unit for TTestService inherited from TService . ; var IsDesktopMode : Boolean; function IsServiceRunning : Boolean; var Svc: Integer; SvcMgr: Integer; ServSt : TServiceStatus; begin Result := False; SvcMgr := OpenSCManager(nil, nil, SC_MANAGER_CONNECT); if SvcMgr = 0 then Exit; try Svc := OpenService(SvcMgr, 'TestService', SERVICE_QUERY_STATUS); if Svc = 0 then Exit; try if not QueryServiceStatus(Svc, ServSt) then Exit; Result := (ServSt.dwCurrentState = SERVICE_RUNNING) or (ServSt.dwCurrentState = SERVICE_START_PENDING); finally CloseServiceHandle(Svc); end; finally CloseServiceHandle(SvcMgr); end; end; begin if (Win32Platform <> VER_PLATFORM_WIN32_NT) or FindCmdLineSwitch('S', ['-', '/'], True) then IsDesktopMode := True else begin IsDesktopMode := not FindCmdLineSwitch('INSTALL', ['-', '/'], True) and not FindCmdLineSwitch('UNINSTALL', ['-', '/'], True) and not IsServiceRunning; end; if IsDesktopMode then begin //desktop mode Forms.Application.Initialize; Forms.Application.Title := 'App. Title'; ShowTrayIcon(Forms.Application.Icon.Handle, NIM_ADD); // This function for create an icon to tray. You can create a popupmenu for the Icon. while GetMessage(Msg, 0, 0, 0) do begin TranslateMessage(Msg); DispatchMessage(Msg); end; ShowTrayIcon(Forms.Application.Icon.Handle, NIM_DELETE); // for delete the tray Icon end else begin // Service mode SvcMgr.Application.Initialize; SvcMgr.Application.CreateForm(TTestService, TestService); SvcMgr.Application.Run; end; end.