Delphi开发Windows服务时OnCreate事件多次触发的原因与解决方案咨询
问题原因
这是Delphi Vcl.SvcMgr单元的原生设计行为,不属于代码bug:
- 你开发的服务exe在执行不同操作时都是独立启动的进程:
- 运行
testsvcserverMonitor /install时是手动启动的独立进程,框架识别到安装参数后会创建服务实例触发OnCreate,安装逻辑执行完成后进程直接退出 - 从服务控制台启动服务时,是Windows服务控制管理器(SCM)启动了全新的exe进程,会重新创建服务实例触发OnCreate,之后执行服务启动逻辑
- 运行
testsvcserverMonitor /uninstall卸载时,又是手动启动的独立进程,同样会创建实例触发OnCreate
- 运行
- 日志中不同场景的Tag值完全不同,刚好验证了每次都是不同进程的全新实例,完全符合预期。
是否需要规避
大部分场景不需要特殊规避,只需要注意代码逻辑的放置位置即可:
- 和安装、卸载相关的初始化逻辑可以放在OnCreate中
- 服务运行时才需要的业务初始化逻辑绝对不要放在OnCreate里,必须写到
OnStart事件中,避免安装、卸载时错误执行业务逻辑引发异常。
优化方案(如需区分场景避免无用逻辑执行)
如果不想让安装、卸载场景执行OnCreate里的服务运行相关代码,可以增加启动参数判断,示例如下:
procedure TApplicationMonitor.ServiceCreate(Sender: TObject); begin Self.Tag := 1000 + Random(1000); // 调试用Tag赋值不受场景影响 ServiceDebugLog('servicecreate'); // 识别当前是否为安装/卸载场景 if FindCmdLineSwitch('install', True) or FindCmdLineSwitch('uninstall', True) then begin // 此处仅放置安装、卸载需要执行的初始化逻辑 Exit; end; // 此处放置仅服务运行时需要执行的初始化逻辑 end;
内容的提问来源于stack exchange,提问作者Jan Doggen
相关产品推荐
相关产品推荐

