避免电脑休眠

公司工作电脑会被域策略强制休眠,从而导致在家无法远程连接.因此需要一个脚本,保证机器处于运行状态.
防止计算机休眠有三种方法:

  • 基于Windows API
  • 基于电源计划
  • 模拟键盘/鼠标

基于Windows API (SetThreadExecutionState)
MSDN解释:Enables an application to inform the system that it is in use, thereby preventing the system from entering sleep or turning off the display while the application is running.
它就是用来干防止电脑休眠和锁屏的。有5个可选参数:

  • ES_AWAYMODE_REQUIRED
  • ES_CONTINUOUS
  • ES_DISPLAY_REQUIRED
  • ES_SYSTEM_REQUIRED
  • ES_USER_PRESENT

要保持电脑不休眠,使用ES_CONTINUOUS | ES_SYSTEM_REQUIRED 就可以了
下面是PowerShell的实现: 1 打印机器启动时间 2 使用c#包装WinAPI,以供PowerShell调用 3 注册C#代码 4 以一定时间间隔循环调用SetThreadExecutionState

# enable local ps execute => Set-ExecutionPolicy RemoteSigned
# another way is using power plan setting http://www.wintellect.com/blogs/jrobbins/setting-the-power-plan-with-powershell
# Last Booted Time
Get-WmiObject -Class Win32_OperatingSystem ComputerName localhost | Select-Object -Property CSName,@{n=Last Booted;e={[Management.ManagementDateTimeConverter]::ToDateTime($_.LastBootUpTime)}}

# WinAPI wrapper
$script:nativeMethods = @();
function Register-NativeMethod([string]$dll, [string]$methodSignature)
{
    $script:nativeMethods += [PSCustomObject]@{ Dll = $dll; Signature = $methodSignature; }
}
function Add-NativeMethods()
{
    $nativeMethodsCode = $script:nativeMethods | % { "
        [DllImport(`"$($_.Dll)`")]
        public static extern $($_.Signature);
    " }

    Add-Type @"
        using System;
        using System.Runtime.InteropServices;
        public static class SetThreadExecutionStateWrapper {
            $nativeMethodsCode
        }
"@
}
Register-NativeMethod "kernel32.dll" "uint SetThreadExecutionState(uint esFlags)"
Add-NativeMethods


function wakeUpOS() {
    $executionValue = [SetThreadExecutionStateWrapper]::SetThreadExecutionState(0x00000000 -bor 0x00000001 -bor 0x00000002)
    write-output $(Get-Date -format 'u')
}

while(1){
    wakeUpOS
    [System.Threading.Thread]::Sleep(5000)
}

GitHub Source Code
下载

基于电源计划 (powercfg.exe)
利用powercfg.exe不停的执行设置电源计划,从而使计数清零并重新开始。
下面是Python的实现(感谢_吴鹏_同学的分享): 1 通过powercfg.exe 设置电源计划 2 以一定时间间隔循环调用

#!/usr/bin/env python
#coding:utf-8
"""
  Author:   --<>
  Purpose: 
  Created: 2014-03-03
  MODIFIED: 2014-03-19
"""

import os
import time
import chardet
import re
import time

command       = u'powercfg -setactive {GUID}'
cmd_list_guid = u'powercfg -list'
reg_str       = u'GUID: (\w+-\w+-\w+-\w+-\w+) +\((.*?)\) ?(\*?)'

def _u(str_buf):
    if not str_buf:
        return str_buf
    if type(str_buf) == str:
        encoding = chardet.detect(str_buf)['encoding']
        return str_buf.decode(encoding)
    else:
        return str_buf
    
def _u8(str_buf):
    if not str_buf:
        return str_buf
    return _u(str_buf).encode('utf8')

def get_powercfg_guids():
    rets = os.popen(cmd_list_guid).read()
    rets = _u(rets)
    guids = re.findall(reg_str, rets)
    index = 0
    all_guids = {}
    for guid in guids:
        all_guids[index] = list(guid)
        index += 1
    return all_guids

if __name__ == '__main__':

    guids = get_powercfg_guids()
    print u'Power Scheme List:'
    for index in guids:
        guid = guids[index]
        print u'%2s: Name: %s\t %s' % (index, guid[1], u'(Active)' if guid[2] else u'')
    print '' 
    

    index = -1
    while index not in guids:
        try:
            index = int(raw_input(u'Choose the Scheme index number you want to keep:'))
        except :
            print u'Can I Hehe?'
            
    power_cfg = guids[index]
    
    while True:
        try:
            os.system(command.format(GUID=power_cfg[0]))
            print u'%s  :  Current Power Scheme is %s (GUID:%s)' % \
                  (time.ctime(), power_cfg[1], power_cfg[0])
        except Exception as ex:
            print ex
        time.sleep(60)

Published: March 18 2014