问题
使用 Delphi 创建一个 Windows Service 工程,编译后可以安装为一个 Windows 的服务。这样的工程,在 Delphi IDE 里面,没有办法 Debug,一运行就退出了。
解决方案
在工程的源代码里面,增加一些编译器指令,在 Debug 模式下,添加代码,把程序当作一个终端程序,并且执行 Readln 阻塞住不要退出,就可以进行断点调试了。
代码如下
Delphi
program MyServicePro;
{$IFDEF DEBUG}
{$APPTYPE CONSOLE} // 调试模式下启用控制台
{$ELSE}
{$APPTYPE GUI} // 发布模式下使用 GUI(服务)
{$ENDIF}
uses
{$IFDEF DEBUG}
Forms,
{$ELSE}
Vcl.SvcMgr,
{$ENDIF }
Web.WebReq,
IdHTTPWebBrokerBridge,
MyService in 'UMyService.pas' {YmDnsService: TService},
DnsDataImpl in '..\Server\DnsDataImpl.pas',
DnsDataIntf in '..\Server\DnsDataIntf.pas',
WebModuleUnit1 in '..\Server\WebModuleUnit1.pas' {WebModule1: TWebModule},
UDmWebServer in 'UDmWebServer.pas' {DmWebServer: TDataModule};
{$R *.RES}
begin
if WebRequestHandler <> nil then
WebRequestHandler.WebModuleClass := WebModuleClass;
{$IFDEF DEBUG}
var B: Boolean;
Application.Initialize;
Application.CreateForm(TMyService, MyService);
Application.CreateForm(TDmWebServer, DmWebServer);
YmDnsService.ServiceStart(nil, b);
Readln;
{$ELSE}
if not Application.DelayInitialize or Application.Installing then
Application.Initialize;
Application.CreateForm(TMyService, MyService);
Application.CreateForm(TDmWebServer, DmWebServer);
Application.Run;
{$ENDIF}
end.
另外一个需要注意的问题
如果你仔细读上面的代码,你会发现我在这里使用了 IdHTTPWebBrokerBridge,这个玩意是用来在这个服务程序里面,内置一个 WEB Server 。
这里就需要有代码启动 WEB Server,打开监听端口。这里需要注意的是,在 Service 模式的程序里面,不要 Service 一启动就立即启动 Web Server,这里必须延时一下再启动,否则会出现异常。异常信息大概是:
raised exception class EIdWinsockStubError with message 'Error on call to Winsock2 library function shutdown: 应用程序没有调用 WSAStartup,或者 WSAStartup 失败。'.
延迟启动的大致代码:
Delphi
FServer: TIdHTTPWebBrokerBridge;
procedure TDmWebServer.DataModuleCreate(Sender: TObject);
begin
FServer := TIdHTTPWebBrokerBridge.Create(Self);
FServer.Bindings.Clear;
FServer.DefaultPort := Self.FPort;
TTask.Run(
procedure
begin
Sleep(1000);
FServer.Active := True;
end
);
end;