我有一个需要在 Windows XP 和 7 上长时间无人值守运行的应用程序。我让它在远程计算机上运行,该计算机具有登录安装后,我就可以从远处查看。该程序有定期的日志记录任务,这些任务由计时器控制。
我注意到,如果将 PC 设置为延迟后屏幕保护,然后在退出屏幕保护程序时显示用户登录屏幕,则我的应用程序将在 PC 进入屏幕保护程序时停止工作。
当我远程登录并将其踢出屏幕保护程序时,它会从中断的地方继续,但在此期间没有记录任何数据。
我以为我可以通过取消选中屏幕保护程序选项中的“恢复时显示欢迎屏幕”复选框来解决这个问题,但问题似乎又出现了。我尝试完全禁用屏幕保护程序 - 但没成功。
我如何确保我的程序始终保持运行? 我知道在欢迎屏幕上 Windows 会告诉我“x 个程序正在运行”,但这似乎并没有延伸到 Windows 计时器,至少有时是这样。
更多信息:
我添加了一些调试代码并获得了更多信息。
该应用程序是 Delphi 2006 GUI 应用程序。它执行的常规任务之一是生成报告。在生成报告时(可能需要一些时间),我会显示一个进度条。这是以模式窗体的形式实现的,其中所有处理都在OnPaint
处理程序中进行。
我发现,如果在屏幕保护程序启动后触发报告,并且选中“恢复时显示欢迎屏幕”复选框,则OnPaint
此模式窗体的方法永远不会触发。窗体的OnShow
事件触发,然后应用程序挂起。一旦我们退出屏幕保护程序并恢复,事件OnPaint
就会执行,一切都会发生。
我最初认为屏幕保护程序处于活动状态时不会触发计时器事件,这是错误的。事实上,用于防止计时器事件重新进入的其他代码阻止了任何事情发生,直到报告完成,并且报告被卡在事件中OnPaint
。
关于如何实现此进度表单,使其在 PC 屏幕保存到欢迎屏幕时运行,有什么建议吗?
答案1
你可以将程序设置为以服务方式运行。这样它就会一直运行在后台。
这样你就可以锁定系统,而你的应用程序仍会运行。
免费工具服务化完全可以满足您的需求。
答案2
您的问题中没有足够的数据来支持这种思路,
因此,我先从一些假设开始,您可以先确认这些假设,然后再进一步阅读答案。
- 您是否在目标机器上使用某种域登录?
- 屏幕保护程序通常在系统锁定时启动
- 在某些配置中,系统锁定时用户登录会丢失
(我不记得这里的确切概念,但如果您远程登录可能会发生这种情况)
简而言之,会话可能会终止...... - 最后,如果您的程序需要网络连接(或仅允许您登录的资源),则会话终止时这些访问权限可能会被撤销。
在这种情况下,应用程序将无法完成。
因此,如果您的情况如此,应用程序将无法完成其活动,因为访问权限被撤销(因为您的会话已结束),当您再次登录以“解锁”系统时,会话将重新启动,您也可以重新启动应用程序(应用程序可能已超时并停止而未达到结果)。但是,由于您现在正在运行新会话,因此它会再次正常启动(但会导致与您让它继续运行相同的问题——最终导致会话终止和屏幕锁定)。
答案3
我知道这听起来可能像是一个更糟糕的解决方案,但你能不能只添加一些代码,每隔几分钟就抽动一下鼠标?没什么大不了的,只需在任一轴上对当前鼠标位置加 1 或减 1 即可。
答案4
我必须采用的最终解决方案是在处理程序中进行处理FormActivate
。然后我必须通过发布消息来关闭表单,因为该方法只有在调用处理程序Close
后才能起作用。与事件不同,事件OnPaint
OnPaint
OnActivate
是当 PC 处于屏幕保护状态时调用。
procedure TReportForm.FormShow (Sender: TObject) ;
begin
OnActivate := FormActivate ; // reinstate the handler (it will be nil from any prior call)
end;
procedure TReportForm.FormActivate (Sender: TObject) ;
begin
OnActivate := nil ; // prevent it being called recursively
GenerateReport ;
PostMessage (Handle, WM_CLOSE, 0, 0) ;
end ;