Question

I'm building a windows service application which has a configuration to compile it as a basic windows application. The main project file for the exe includes conditionals which determine whether the project is being compiled as a service application or as a windows forms application.

The problem is, when I do something which makes the project code change, the code gets destroyed and broken. For example, a line which says Application.Initialize; becomes AppliApplication.Initialize; and the line which has {$R *.RES} gets cut down to S}, and most of my conditionals get deleted.

I'm wondering if there is a way to overcome this issue, if there are any tricks, or if I just have to grin and bear it?

Here's the file below as I would like it to stay...

program JDRMServer;

uses
{$IFDEF TESTAPP}
  FastMM4,
  Vcl.Forms,
{$ELSE}
  Vcl.SvcMgr,
{$ENDIF TESTAPP}
  uJDRMServer in 'uJDRMServer.pas' {JDRMSvr: TService},
  uJDRMSessions in 'uJDRMSessions.pas',
  uJDRMSvrCli in 'uJDRMSvrCli.pas',
  uJDRMSvrDsh in 'uJDRMSvrDsh.pas',
  JDDB in 'JDDB.pas',
  uJDRMServerTEST in 'uJDRMServerTEST.pas' {JDRMSvrTest},
  uJDRMServerThread in 'uJDRMServerThread.pas',
  uJDRMSvrMessages in 'uJDRMSvrMessages.pas';

{$R *.RES}

begin

{$IFDEF TESTAPP}
  Application.Initialize;
  Application.MainFormOnTaskbar := True;
  Application.CreateForm(TJDRMSvrTest, JDRMSvrTest);
{$ELSE}
  if (not Application.DelayInitialize) or (Application.Installing) then
    Application.Initialize;
  Application.CreateForm(TJDRMSvr, JDRMSvr);
{$ENDIF TESTAPP}
  Application.Run;
end.
Was it helpful?

Solution

As David says, you are stuck with the IDE believing the dpr is its own private backyard. The easiest solution is to just have everything in a separate unit and remove the conditionals from the dpr's uses clause. FastMM will come in handy in your service version as well as in your test app anyway and the distinction between vcl.forms and vcl.svcMgr can be made in that separate unit.

dpr would be reduced to:

uses
  FastMM4,
  YourAppMain,
  uJDRMServer,
  uJDRMSessions,
  uJDRMSvrCli in 'uJDRMSvrCli.pas',
  uJDRMSvrDsh in 'uJDRMSvrDsh.pas',
  JDDB in 'JDDB.pas',
  uJDRMServerTEST in 'uJDRMServerTEST.pas' {JDRMSvrTest},
  uJDRMServerThread in 'uJDRMServerThread.pas',
  uJDRMSvrMessages in 'uJDRMSvrMessages.pas';

{$R *.RES}

begin
  YourAppMain.Execute;
end;

And your main application unit would take the rest of the code from the dpr:

unit YourAppMain;

interface

procedure Execute;

implementation

uses
{$IFDEF TESTAPP}
  Vcl.Forms,
{$ELSE}
  Vcl.SvcMgr,
{$ENDIF TESTAPP}
  OtherUnits;

procedure Execute;
begin
{$IFDEF TESTAPP}
  Application.Initialize;
  Application.MainFormOnTaskbar := True;
  Application.CreateForm(TJDRMSvrTest, JDRMSvrTest);
{$ELSE}
  if (not Application.DelayInitialize) or (Application.Installing) then
    Application.Initialize;
  Application.CreateForm(TJDRMSvr, JDRMSvr);
{$ENDIF TESTAPP}
  Application.Run;
end;

end.

OTHER TIPS

The simple answer is to just create a different project and use that as the standalone version. This is what I do with my services, and it means you can use other conditionals to suit each mode.

Yes, the IDE does that and always has done. There is no known way to stop it behaving like that. You are just going to have to suck it up.

I have similar conditionals and the way I deal with them is to use my revision control system to help me, at commit time, undo the changes that the IDE makes. So whenever I check in a .dpr file I review the differences and revert the bogus ones.

I also try to add and remove units from the project by editing the .dpr file rather than letting the IDE do it. This tends to reduce the incidence rate of the bogus mods.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top