如何防止Windows捕获我的Perl异常?

4
我有一个Perl软件,它应该24/7运行。它保持与IMAP服务器的连接,检查新邮件,然后分类新消息。
现在我有一个用户不时地让他的XP笔记本电脑休眠。发生这种情况时,与服务器的连接会失败并触发异常。调用代码通常会捕获该异常并尝试重新连接。但在这种情况下,似乎Windows(或Perl?)捕获了异常并通过消息框将其传递给用户。
有人知道如何防止这种奇怪的事情发生吗?我的代码是否可以捕获“系统即将休眠”的信号?
为了澄清一些你已经提出的问题:
  • 我不介意用户将他们的计算机休眠。我只需要找到一种处理它的方法。
  • 涉及的Perl模块确实会抛出异常。它会执行类似于"die 'foo bar'"的操作。虽然应用程序完全基于浏览器,不使用类似于Wx或Tk的任何东西,但用户会得到一个标题为"poll_timer"的消息框。该消息框的内容正是$@的内容(在这个例子中是'foo bar')。
  • 该应用程序使用perlapp编译成可执行文件。文档没有提到任何关于异常处理的内容。
4个回答

1

我认为你正在处理操作系统级别的异常,而不是 Perl 抛出的异常。相关的 Perl 模块在调用 DLL 中的某些内容(我猜测),并且引发了异常。您最好将其简化为一个简单可复制的测试用例,以触发此异常(您可能需要在涉及的计算机上进行多次休眠和唤醒操作)。然后,将此信息发送给模块开发人员,并询问他们是否可以想出一种更有用的方式来捕获此异常。

如果模块开发人员无法或不愿提供帮助,则您可能需要使用 Perl 调试器来调试模块的代码,以查看到底发生了什么,并查看是否有一种方法可以更改模块本身以捕获和处理异常。


好消息是我是Perl模块的开发者。坏消息是异常确实是由Perl抛出的,但必须以某种方式提升到操作系统级别。 - innaM
如果它是由Perl抛出的(而不是通过Perl与之交互的DLL,包括编译为Perl模块的C代码到DLL中),那么捕获它应该很容易。将其包装在eval中。 - skiphoppy
在这种情况下,我真的很难相信这是真正的 Perl 异常,而不是 Windows 的问题。你能将它简化为一个短小的独立测试用例来抛出异常吗?在那个测试用例中你调用了什么?Windows 代码吗? - skiphoppy
我很同情。问题在于我目前没有办法在Windows上进行测试。但归根结底,这真的只是eval { do_some_networking() or die };的问题。我猜机器在进行网络操作时会进入休眠状态。 - innaM
Manni,如果你是一个模块的作者,那么你需要查看这篇新闻。链接 - skiphoppy
是的。我一直希望有一天能够动手做这个。 - innaM

0

你的用户并非例外,而是规则。 我的笔记本电脑在工作和家庭之间休眠。 在工作时,它连接到 DHCP 网络;在家里,它连接到另一个网络。 大多数程序即使有多个 IP 地址(VMWare、VPN、普通的 NAT 路由器连接),仍然可以正常运行。 那些不能正常工作的程序(AT&T Net Client,用于 VPN - 在办公室未使用,在家或在路上需要),在休眠时识别到断开连接(AT&T Net Client 将挂起 StandBy/Hibernate 进程直到断开连接),如果适当的话,我会在机器唤醒时重新建立连接。 在机场,我使用本地 WiFi(更多的 DHCP),但在登机前完全关闭无线连接(一个物理开关)。

因此,你需要找出如何了解机器何时进入 StandBy 或 Hibernation 模式,以便你的软件可用。 不过,很抱歉我没有一个能帮到你的方法。

一些与 Google 的工作表明,ACPI(高级配置和电源接口)是解决方案的一部分(Microsoft)。 APM(高级电源管理)也可能相关。


0

如果没有看到相关的代码片段,很难提供智能建议。如果您收到一个带有异常消息的对话框,那么程序很可能使用TkwxPerl GUI库,这可能会使事情变得有点复杂。话虽如此,我猜想在程序中修改异常处理应该是相当容易的,只需将失败点包装在eval块中,并在调用后测试$@。如果$@包含指示连接失败的错误消息,则重新建立连接并继续进行。


我既不使用Tk也不使用Wx。该应用程序完全基于浏览器。这就是为什么我对那个消息框有点困惑的原因。我的应用程序不知道如何生成消息框。 - innaM

0

我发现了一种避免模态系统对话框的方法,以解决硬错误(例如“遇到异常并需要关闭”)。我不知道相同的技巧是否适用于您所描述的此类错误,但您可以尝试一下。

参考链接:避免Windows出现“遇到问题需要关闭”对话框

简单来说,将注册表键 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Windows\ErrorMode 的值设置为“2”。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接