7.9 KiB
使用 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 包。
这是我从我模糊的过去得到的食谱:
# 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()
在这个代码片段中,我实际上去掉了重启远程机器的功能,因为我不想这么做。如果要重新启动网络上的计算机,请更改以下行:
win32api.InitiateSystemShutdown(None, message, timeout, bForce, bReboot)
到
win32api.InitiateSystemShutdown("someMachineName", message, timeout, bForce, bReboot)
或者只需向 RebootServer 函数添加一个主机参数,并根据需要修改 InitiateSystemShutdown。如果你只是传递 None 进去,那么你只是重新启动你自己的机器。 AdjustPrivilege 方法用于改变进程的特权,这样它就可以关闭电脑。我认为这只适用于你作为一个拥有有限权限的用户运行脚本的情况,但是我几乎从来没有这样运行过,所以我不能确定。我记得菜谱上说您需要删除您添加的特权,这就是 finally 语句的作用。然而,我认为一旦重启完成,这些特权无论如何都会被取消。
用普通的 Python 重启
启动关机的另一种方法是学习 Windows 命令行的魔力。有一个关机命令,你可以把你的运行对话框(进入开始->运行),这将重新启动你的电脑。这里有一个我说的:shutdown -r -t 1 注意这只会重启本地机器!
现在我们只需要弄清楚如何让 Python 为我们调用它。可能最简单的方法是导入 os 模块并调用它的系统方法。让我们来看看:
import os
os.system("shutdown -r -t 1")
这比 PyWin32 方法短得多,但我不知道它是否同样健壮。我在一个快速而肮脏的 wxPython 应用程序中使用了这个方法,这个应用程序是我为工作中的 Sun Ray 虚拟机创建的。Sun Ray 系统的最大问题之一是用户使用远程桌面连接到他们的虚拟机。远程桌面的一部分是隐藏关机按钮,所以用户没有简单的方法来重新启动他们的电脑,除非他们安装了某种修复程序。有时候重启机器是一件好事,所以我将上面的脚本放入下面的应用程序中:
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()
我看了这个项目的很多图标,我想我最后只是搜索了一下关机和注销图标,然后下载了我最喜欢的图标。这两个都是免费的或者有知识共享许可。
现在您知道了重启本地和远程机器的技巧。明智地使用这些知识!
