Python保存设置为Windows关闭时的文件?

时间:2014-08-03 11:16:05

标签: python python-2.7 shutdown power-management

如果Windows即将关闭/重启/注销/休眠,我不想丢失我的设置,是否可以在关机前保存它?或者有没有替代方法来保存信息而不必担心它会在Windows关机时丢失? JSON,CSV,DB?什么?

s = {1,2,3,4}

with open("s.pick","wb") as f: # pickle it to file when PC about to shutdown to save information
    pickle.dump(s,f)

2 个答案:

答案 0 :(得分:3)

您可以使用win32api.setConsoleCtrlHandler

检测Windows关闭/注销

有一个很好的例子How To Catch “Kill” Events with Python

答案 1 :(得分:3)

  

如果Windows即将关闭/重启/注销/休眠,我不想丢失我的设置,是否可以在关机前保存它?

是的,如果您使用消息循环构建了应用,则可以收到WM_QUERYENDSESSION消息。如果你想拥有一个GUI,大多数GUI库可能会以自己的方式包装它。如果您不需要GUI,最简单的解决方案可能是使用PyWin32。在文档的某个地方,有一个关于创建隐藏窗口和编写简单消息循环的教程。只需在主线程上执行此操作,并在后台线程上执行您的实际操作,并在WM_QUERYENDSESSION消息进入时发出后台线程信号。

或者更简单地说,正如Evgeny Prokurat建议的那样,只需使用SetConsoleCtrlHandler(再次通过PyWin32)。这也可以捕获^ C,^ BREAK,以及关闭控制台的用户,以及WM_QUERYENDSESSION捕获的注销和关闭消息。更重要的是,它不需要一个消息循环,所以如果你不需要一个消息循环,那就更简单了。


  

或者是否有其他方法可以保存信息而不必担心它会在Windows关闭时丢失? JSON,CSV,DB?什么?

文件格式不会神奇地解决任何问题。但是,数据库可能有两个优点。

首先,您可以通过尽可能多地书写来减少问题。但是对于大多数文件格式,这意味着尽可能频繁地重写整个文件,这将非常慢。解决方案是流式传输到更简单的期刊"文件,不经常将其打包到真实文件中,并在每次发布时查找剩余的日志。您可以手动执行此操作,但数据库通常会自动为您执行此操作。

其次,如果你在写作过程中被杀,你最终会得到半个文件。您可以通过原子写入技巧解决这个问题 - 写一个临时文件,然后用临时文件替换旧文件 - 但这很难在Windows上得到正确(特别是使用Python 2.x)(参见Getting atomic writes right),而且,数据库通常会为您完成。


"对"这样做的方法是创建一个带有msgproc的新窗口类,该窗口调度到WM_QUERYENDSESSION上的处理程序。正如MFC使这比原始Win32 API代码更容易,win32ui(包装MFC)使这比win32api / win32gui(包装原始Win32 API)更容易。你可以找到很多样本(例如,快速搜索" pywin32 msgproc示例"显示像this的示例,并搜索" python win32ui"和类似术语同样有效。)

然而,在这种情况下,你没有一个你想要像普通窗口一样工作的窗口,因此可能更容易直接进入低级别并编写一个快速和简单的消息循环。不幸的是,找到示例代码要困难得多 - 您基本上必须在本机API中搜索C示例代码(如MSDN上的Creating a Message Loop),然后弄清楚如何将其转换为Python { {1}}文档。不太理想,特别是如果你不了解C,但 很难。这是一个让你入门的例子:

pywin32

我还没有展示如何创建一个最小的隐藏窗口"部分,或如何指示工人停下来,例如def msgloop(): while True: msg = win32gui.GetMessage(None, 0, 0) if msg and msg.message == win32con.WM_QUERYENDSESSION: handle_shutdown() win32api.TranslateMessage(msg) win32api.DispatchMessage(msg) if msg and msg.message == win32con.WM_QUIT: return msg.wparam worker = threading.Thread(real_program) worker.start() exitcode = msgloop() worker.join() sys.exit(exitcode) ,因为这些部分有更多(更容易找到)的好样本;这是一个棘手的部分。