Delphi 表单销毁的意外调用

Delphi 表单销毁的意外调用,delphi,Delphi,我有一项针对客户的服务,特别是我注意到了一种奇怪的行为。总是在关闭服务之前,执行关闭例程(OnStop),然后输入FormDestroy。但是,在这个客户中,服务意外终止(我知道这是因为FormDestroy一直在调用),但没有进入服务关闭的例程 从堆栈上看,一切似乎都很正常: 01388f14 ****.exe Main****. 32766 TF****.FormDestroy 00506cbd ****.exe Forms TCustomForm.D

我有一项针对客户的服务,特别是我注意到了一种奇怪的行为。总是在关闭服务之前,执行关闭例程(OnStop),然后输入FormDestroy。但是,在这个客户中,服务意外终止(我知道这是因为FormDestroy一直在调用),但没有进入服务关闭的例程

从堆栈上看,一切似乎都很正常:

01388f14 ****.exe Main****. 32766 TF****.FormDestroy 00506cbd ****.exe Forms TCustomForm.DoDestroy 00506b23 ****.exe Forms TCustomForm.BeforeDestruction 00404c95 ****.exe System @BeforeDestruction 007a6a02 ****.exe dxRibbonForm 445 TdxCustomRibbonForm.Destroy 00487eaa ****.exe Classes TComponent.DestroyComponents 00504a33 ****.exe Forms DoneApplication 0045da9d ****.exe SysUtils DoExitProc 00405683 ****.exe System @Halt0 01435465 ****.exe Main**** 289 initialization 75773388 kernel32.dll BaseThreadInitThunk 01388f14****.exe主****。32766 TF****表格销毁 00506cbd****.exe表单TCustomForm.DoDestroy 00506b23****.exe在销毁前形成TCustomForm 00404c95****.exe系统@销毁前 007a6a02****.exe dxRibbonForm 445 TdxCustomRibbonForm.Destroy 00487eaa****.exe类TComponent.DestroyComponents 00504a33****.exe表单不适用 0045da9d****.exe SysUtils DoExitProc 00405683****.exe System@Halt0 0145465****.exe主****289初始化 75773388 kernel32.dll BaseThreadInitThunk 我可以在Windows事件查看器中看到此消息:

找不到源***中事件ID 0的说明。引发此事件的组件未安装在本地计算机上,或者安装已损坏。您可以在本地计算机上安装或修复该组件

如果事件起源于另一台计算机,则显示信息必须与事件一起保存

本次活动包括以下信息:

已注册扩展处理程序


你能给我一个提示,看看会发生什么事吗

事件查看器中的消息没有意义。这只是事件的标准错误文本,而作为事件源的应用程序没有提供包含适当错误消息的DLL来描述特定事件

由于您的服务似乎试图以交互方式运行(使用UI),因此您可能已将服务的Interactive属性设置为TRUE。这意味着您的服务从服务交互\u过程开始。根据系统设置,系统可能会阻止使用此标志启动的服务运行

总之,在注册表的HKEY\U LOCAL\U MACHINE\SYSTEM\CurrentControlSet\Control\Windows项中,如果NoInteractiveServices值设置为1(零),则这些服务将无法运行。对于Delphi实现的服务,这意味着服务过程已启动,但在尝试注册服务本身时将终止,如果服务过程包含服务UI初始化成功的假设,则可能会导致UI销毁代码出现问题

在受影响的客户系统上,将此注册表值更改为0(零)以允许交互式服务。如果您的服务能够启动,那么这将确认这是问题的根源

但是,您的客户可能出于合理的原因特别选择不允许此类服务(请参阅该文章中的注释)


如果是这种情况,并且这确实是您的问题的原因,那么您将不得不为您的服务/应用程序的UI需求找到一种替代方法。同时,如果使用您的服务对该客户很重要,那么如果他们准备在您对应用程序体系结构进行必要更改的同时在受影响的系统上启用此设置一段有限的时间,那么这可能会提供一个临时解决方案。

让我们从您的代码开始。你能分享你的服务是如何停止的吗?没有它,我怀疑除了你自己以外的任何人都能猜出问题所在。@DavidHeffernan服务可以有GUI。。。也许他们拥有它们并不“明智”,但说它们“不允许”是错误的,在这里没有帮助。@Ian没有。服务不能有GUI。它们在会话0中运行,该会话不是交互式的。@DavidHeffernan我使用GUI维护一个服务。它在XP上运行良好。在Windows 7中,这有点麻烦,因为您必须使用交互式桌面服务来访问它-但他们可以拥有它们。@Ian这不是真的。自Vista以来,服务在会话0中运行。“允许服务与桌面交互”选项仅允许服务与会话0中交互用户看不到的桌面交互。您不应该使用该选项,即使是在XP中,因为存在安全风险。您应该有一个单独的桌面应用程序,使用IPC与服务进行通信。整个问题在MSDN上有全面的记录。尝试在会话0中创建GUI对象通常会导致错误,问题中的堆栈跟踪使我认为这发生在询问者身上。考虑到这一点,答案很有趣。