198 lines
7.9 KiB
Markdown
198 lines
7.9 KiB
Markdown
|
|
# 使用 Python 重启电脑
|
|||
|
|
|
|||
|
|
> 原文:<https://www.blog.pythonlibrary.org/2010/03/27/restarting-pcs-with-python/>
|
|||
|
|
|
|||
|
|
你有没有想过重新启动你的 Windows 电脑没有按下开始,关机或 CTRL+ALT+DEL?重启你讨厌的同事的电脑怎么样...就是那个不知道什么时候该闭嘴的人?Python 给出了答案,这个博客将告诉你如何去做!注意:我并不建议你随意重启邻居的电脑...
|
|||
|
|
|
|||
|
|
## 使用 PyWin32 重新启动
|
|||
|
|
|
|||
|
|
无论如何,当我第一次学习 Python 时,我偶然发现了一个关于如何做到这一点的 ActiveState 方法。当然,现在我似乎找不到那个配方了,但是我在这里找到了一个相似的:http://code.activestate.com/recipes/360649/.因此,我们将首先从这个方法开始,然后看一个稍微不同的方法。如果你想跟着做,那么你需要确保你有 [PyWin32 包](http://sourceforge.net/projects/pywin32/files/)。
|
|||
|
|
|
|||
|
|
这是我从我模糊的过去得到的食谱:
|
|||
|
|
|
|||
|
|
```py
|
|||
|
|
|
|||
|
|
# rebootServer.py
|
|||
|
|
|
|||
|
|
import win32security
|
|||
|
|
import win32api
|
|||
|
|
import sys
|
|||
|
|
import time
|
|||
|
|
from ntsecuritycon import *
|
|||
|
|
|
|||
|
|
def AdjustPrivilege(priv, enable=1):
|
|||
|
|
# Get the process token
|
|||
|
|
flags = TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY
|
|||
|
|
htoken = win32security.OpenProcessToken(win32api.GetCurrentProcess(), flags)
|
|||
|
|
# Get the ID for the system shutdown privilege.
|
|||
|
|
idd = win32security.LookupPrivilegeValue(None, priv)
|
|||
|
|
# Now obtain the privilege for this process.
|
|||
|
|
# Create a list of the privileges to be added.
|
|||
|
|
if enable:
|
|||
|
|
newPrivileges = [(idd, SE_PRIVILEGE_ENABLED)]
|
|||
|
|
else:
|
|||
|
|
newPrivileges = [(idd, 0)]
|
|||
|
|
# and make the adjustment
|
|||
|
|
win32security.AdjustTokenPrivileges(htoken, 0, newPrivileges)
|
|||
|
|
|
|||
|
|
def RebootServer(message='Rebooting', timeout=30, bForce=0, bReboot=1):
|
|||
|
|
AdjustPrivilege(SE_SHUTDOWN_NAME)
|
|||
|
|
try:
|
|||
|
|
win32api.InitiateSystemShutdown(None, message, timeout, bForce, bReboot)
|
|||
|
|
finally:
|
|||
|
|
# Now we remove the privilege we just added.
|
|||
|
|
AdjustPrivilege(SE_SHUTDOWN_NAME, 0)
|
|||
|
|
|
|||
|
|
def AbortReboot():
|
|||
|
|
AdjustPrivilege(SE_SHUTDOWN_NAME)
|
|||
|
|
try:
|
|||
|
|
win32api.AbortSystemShotdown(None)
|
|||
|
|
finally:
|
|||
|
|
AdjustPrivilege(SE_SHUTDOWN_NAME, 0)
|
|||
|
|
|
|||
|
|
if __name__ == '__main__':
|
|||
|
|
RebootServer()
|
|||
|
|
time.sleep(10)
|
|||
|
|
print 'Aborting shutdown'
|
|||
|
|
AbortReboot()
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
在这个代码片段中,我实际上去掉了重启远程机器的功能,因为我不想这么做。如果要重新启动网络上的计算机,请更改以下行:
|
|||
|
|
|
|||
|
|
```py
|
|||
|
|
|
|||
|
|
win32api.InitiateSystemShutdown(None, message, timeout, bForce, bReboot)
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
到
|
|||
|
|
|
|||
|
|
```py
|
|||
|
|
|
|||
|
|
win32api.InitiateSystemShutdown("someMachineName", message, timeout, bForce, bReboot)
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
或者只需向 *RebootServer* 函数添加一个主机参数,并根据需要修改 InitiateSystemShutdown。如果你只是传递 *None* 进去,那么你只是重新启动你自己的机器。 *AdjustPrivilege* 方法用于改变进程的特权,这样它就可以关闭电脑。我认为这只适用于你作为一个拥有有限权限的用户运行脚本的情况,但是我几乎从来没有这样运行过,所以我不能确定。我记得菜谱上说您需要删除您添加的特权,这就是 *finally* 语句的作用。然而,我认为一旦重启完成,这些特权无论如何都会被取消。
|
|||
|
|
|
|||
|
|
## 用普通的 Python 重启
|
|||
|
|
|
|||
|
|
启动关机的另一种方法是学习 Windows 命令行的魔力。有一个关机命令,你可以把你的运行对话框(进入开始->运行),这将重新启动你的电脑。这里有一个我说的:shutdown -r -t 1 *注意这只会重启本地机器!*
|
|||
|
|
|
|||
|
|
现在我们只需要弄清楚如何让 Python 为我们调用它。可能最简单的方法是导入 *os* 模块并调用它的*系统*方法。让我们来看看:
|
|||
|
|
|
|||
|
|
```py
|
|||
|
|
|
|||
|
|
import os
|
|||
|
|
os.system("shutdown -r -t 1")
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
这比 PyWin32 方法短得多,但我不知道它是否同样健壮。我在一个快速而肮脏的 wxPython 应用程序中使用了这个方法,这个应用程序是我为工作中的 Sun Ray 虚拟机创建的。Sun Ray 系统的最大问题之一是用户使用远程桌面连接到他们的虚拟机。远程桌面的一部分是隐藏关机按钮,所以用户没有简单的方法来重新启动他们的电脑,除非他们安装了某种修复程序。有时候重启机器是一件好事,所以我将上面的脚本放入下面的应用程序中:
|
|||
|
|
|
|||
|
|
[](https://www.blog.pythonlibrary.org/wp-content/uploads/2010/03/restarter.png)
|
|||
|
|
|
|||
|
|
```py
|
|||
|
|
|
|||
|
|
import os
|
|||
|
|
import wx
|
|||
|
|
from wx.lib.buttons import GenBitmapButton
|
|||
|
|
|
|||
|
|
########################################################################
|
|||
|
|
class RestarterPanel(wx.Panel):
|
|||
|
|
""""""
|
|||
|
|
|
|||
|
|
#----------------------------------------------------------------------
|
|||
|
|
def __init__(self, parent):
|
|||
|
|
"""Constructor"""
|
|||
|
|
wx.Panel.__init__(self, parent=parent)
|
|||
|
|
|
|||
|
|
img = wx.Bitmap("cute-logoff.png")
|
|||
|
|
logoutBtn = GenBitmapButton(self, wx.ID_ANY, img, style=wx.BORDER_NONE)
|
|||
|
|
logoutBtn.Bind(wx.EVT_BUTTON, self.onLogout)
|
|||
|
|
|
|||
|
|
img = wx.Bitmap("quick_restart.png")
|
|||
|
|
restartBtn = GenBitmapButton(self, wx.ID_ANY, img, style=wx.BORDER_NONE)
|
|||
|
|
restartBtn.Bind(wx.EVT_BUTTON, self.onRestart)
|
|||
|
|
|
|||
|
|
cancelBtn = wx.Button(self, label="Cancel")
|
|||
|
|
cancelBtn.Bind(wx.EVT_BUTTON, self.onCancel)
|
|||
|
|
|
|||
|
|
vSizer = wx.BoxSizer(wx.VERTICAL)
|
|||
|
|
sizer = wx.BoxSizer(wx.HORIZONTAL)
|
|||
|
|
sizer.Add(self.buttonBuilder("Logout", logoutBtn), 0, wx.CENTER)
|
|||
|
|
sizer.Add(self.buttonBuilder("Restart", restartBtn), 0, wx.CENTER)
|
|||
|
|
vSizer.Add(sizer, 0, wx.CENTER)
|
|||
|
|
vSizer.Add(cancelBtn, 0, wx.ALIGN_RIGHT|wx.ALL, 5)
|
|||
|
|
self.SetSizer(vSizer)
|
|||
|
|
|
|||
|
|
#----------------------------------------------------------------------
|
|||
|
|
def buttonBuilder(self, label, button):
|
|||
|
|
"""
|
|||
|
|
Creates a button with a label underneath it and puts them into
|
|||
|
|
a vertical BoxSizer, which is then returned
|
|||
|
|
"""
|
|||
|
|
font = wx.Font(12, wx.SWISS, wx.NORMAL, wx.BOLD)
|
|||
|
|
sizer = wx.BoxSizer(wx.VERTICAL)
|
|||
|
|
sizer.Add(button, 0, wx.ALL, 3)
|
|||
|
|
|
|||
|
|
lbl = wx.StaticText(self, label=label)
|
|||
|
|
lbl.SetFont(font)
|
|||
|
|
sizer.Add(lbl, 0, wx.CENTER|wx.BOTTOM, 4)
|
|||
|
|
|
|||
|
|
return sizer
|
|||
|
|
|
|||
|
|
#----------------------------------------------------------------------
|
|||
|
|
def onCancel(self, event):
|
|||
|
|
"""
|
|||
|
|
Close the dialog
|
|||
|
|
"""
|
|||
|
|
self.GetParent().Close()
|
|||
|
|
|
|||
|
|
#----------------------------------------------------------------------
|
|||
|
|
def onLogout(self, event):
|
|||
|
|
"""
|
|||
|
|
Logs the current user out
|
|||
|
|
"""
|
|||
|
|
os.system("shutdown -t 0 -l")
|
|||
|
|
|
|||
|
|
#----------------------------------------------------------------------
|
|||
|
|
def onRestart(self, event):
|
|||
|
|
"""
|
|||
|
|
Restarts the PC
|
|||
|
|
"""
|
|||
|
|
os.system("shutdown -r -t 1")
|
|||
|
|
|
|||
|
|
########################################################################
|
|||
|
|
class RestarterFrame(wx.Frame):
|
|||
|
|
""""""
|
|||
|
|
|
|||
|
|
#----------------------------------------------------------------------
|
|||
|
|
def __init__(self):
|
|||
|
|
"""Constructor"""
|
|||
|
|
wx.Frame.__init__(self, None, size=(273, 169))
|
|||
|
|
panel = RestarterPanel(self)
|
|||
|
|
self.Center()
|
|||
|
|
|
|||
|
|
########################################################################
|
|||
|
|
class Main(wx.App):
|
|||
|
|
""""""
|
|||
|
|
|
|||
|
|
#----------------------------------------------------------------------
|
|||
|
|
def __init__(self, redirect=False, filename=None):
|
|||
|
|
"""Constructor"""
|
|||
|
|
wx.App.__init__(self, redirect, filename)
|
|||
|
|
dlg = RestarterFrame()
|
|||
|
|
dlg.Show()
|
|||
|
|
|
|||
|
|
#----------------------------------------------------------------------
|
|||
|
|
if __name__ == "__main__":
|
|||
|
|
app = Main()
|
|||
|
|
app.MainLoop()
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
我看了这个项目的很多图标,我想我最后只是搜索了一下[关机](http://commons.wikimedia.org/wiki/File:Quick_restart.png)和[注销](http://www.iconfinder.net/icondetails/32136/128/?q=cute)图标,然后下载了我最喜欢的图标。这两个都是免费的或者有知识共享许可。
|
|||
|
|
|
|||
|
|
现在您知道了重启本地和远程机器的技巧。明智地使用这些知识!
|