Paul
Paul

Reputation: 26650

Double click on Windows Service executable to configure

I wrote a Delphi Win32 Windows Service application from Delphi IDE's template, and it works very well when installed and started from Services control panel.

Now I would like to write a configuration application for it and I thought that may be it could be a configurator for itself when just double clicking on its executable.

I think so because when double clicked, the service distinguishes somehow that it wasn't executed by Service Control Management system.

So here are my questions:

  1. How does the Service app distinguishes a simple run and run as a service?
  2. Could the simple run be used to take some actions other than a service mode? Will this disturb functioning in a service mode?

Upvotes: 1

Views: 317

Answers (1)

whosrdaddy
whosrdaddy

Reputation: 11860

to answer your questions:

How does the Service app distinguishes a simple run and run as a service?

look at the code behind TServiceApplication.CreateForm in unit Vcl.SVcMgr

Could the simple run be used to take some actions other than a service mode?

Yes, see below answer

Will this disturb functioning in a service mode?

No

All you need to do is change your Service source code (.dpr file) to something like this:

 begin
  if FindCmdLineSwitch('config', ['-', '/'], True) then
   TMyForm.Run
  else
   begin
    if not Application.DelayInitialize or Application.Installing then
     Application.Initialize;
    Application.CreateForm(TSvc_MyService, Svc_MyService);
    Application.Run;
   end;
end.

where TMyForm.Run is defined as a class procedure on my main GUI form:

class procedure TMyForm.Run;
begin
 TThread.NameThreadForDebugging('FormRunner');
 ReportMemoryLeaksOnShutdown := DebugHook <> 0;
 Forms.Application.Initialize;
 Forms.Application.ShowMainForm := True;
 Forms.Application.MainFormOnTaskBar := True;
 Forms.Application.CreateForm(TMyForm, MyForm);
 Forms.Application.Run;
end;

So when you start the service executable with flag /config (or -config), it will start as a normal forms application.

Update

The distinction is more likely to be made here:

procedure TServiceStartThread.Execute;
begin
  if StartServiceCtrlDispatcher(FServiceStartTable[0]) then
    ReturnValue := 0
  else
    ReturnValue := GetLastError; //Code 1063 if started like an app
end;

This causes WM_QUIT message to be posted to message queue.

Following loop terminates when receives WM_QUIT message.

procedure TServiceApplication.Run;
.....
begin
  .....
  while not Vcl.Forms.Application.Terminated do
  try
    Vcl.Forms.Application.HandleMessage;
  except
    on E: Exception do
      DoHandleException(E);
  end;
  .....
end;

More information on the topic here:

Upvotes: 6

Related Questions