【保存版】Windows10のタスクスケジューラでスリープ解除する方法(ハマりどころあり)

タスクスケジューラを使って,自動的にスリープさせたり,スリープ解除させたいことがあるかもしれません。

例えば,毎日同じ時刻に自動的にパソコンを起動して音楽を再生し,その後,ある時刻に自動的にスリープさせるなどです。

しかし,ネット上で調べた限り,現在有効ではない方法ばかりが載せられており,Windows 10の最新版では動かない方法が広く流布されているようでした。

少なくとも,現時点で有効な日本語での情報はほどんど見当たりませんでした。

代表的なハマりポイントと回避策は以下の通りです。

スリープはできるが,スリープ解除ができない。→PowerShellでSetSuspendStateを正しく設定する。
スリープ解除できるが,モニタがスリープから復帰できず,暗いままになってしまう。→WakeDisp2を使う。
スリープ解除までに,数十秒かかることがあり,スリープ解除に失敗したと思い込んでしまう。→指定時刻から30秒程度待つ必要がある。

それで,数日かけて調べた,はまりどころを回避したタスクスケジューラの設定をまとめておきたいと思います。

Windows 10でタスクスケジューラを設定する際の前提

このページにたどり着いた方であれば,すでにご存じのことと思いますので細かい説明は割愛しますが,タスクスケジューラを使ってスリープ解除するためには,以下の設定を行う必要があります。

「タスクを実行するためにスリープを解除する」にチェックを入れる

「タスクを実行するためにスリープを解除する」にチェックを入れる。

「タスクを実行するためにスリープを解除する」にチェックを入れる。

電源オプションから「スリープ解除タイマーの許可」を「有効」にする

電源オプションから「スリープ解除タイマーの許可」を「有効」にする

電源オプションから「スリープ解除タイマーの許可」を「有効」にする

このあたりは,色々なページで解説されていますので,問題ないかと思います。

Windows 10でタスクスケジューラからスリープ解除できなかった無効な方法

さて,うまくいかない方法から説明したいと思います。

以下の方法がかなり流布されているのですが,これはWindows 10の最新版において,すでに無効な方法となっています。

rundll32.exeを使う方法

以下のコマンドがスリープに入れるためのコマンドとしてよく載っているのですが,この方法でスリープに入れると,タスクスケジューラでスリープを解除することができません。

rundll32.exe powrprof.dll,SetSuspendState Sleep

PowerShellのコマンドで,キーやマウスの入力操作をスケジュールする

スリープ解除時に,PowerShellでマウスの移動やキー入力を疑似的に実行する方法が書かれていたりしますが,これでは,ユーザーからのインタラクティブな入力操作とは見なされず,スリープ解除,あるいはモニタのスリープ解除を実現させることができません。

suspend.exeを使ったスリープ解除の方法

あるサイトで配布されているRubyを元にしたsuspend.exeという実行ファイルですが,これも,現時点では,動かないように思います。少なくとも私の最新版のWindows 10の環境では,タスクスケジューラでスリープ解除させることができませんでした。

BIOSの設定

BIOSの起動設定を見直してみることが勧められていたりもしますが,これは,BIOSでスケジュールした時刻に電源を入れるという,全然別の話です。スリープ解除には特に影響を及ぼしませんので,BIOSまわりで時間を浪費するのはやめましょう。

 

Windows 10のタスクスケジューラでスリープ解除するためにたどり着いた結論

さて,ここからが成功した方法ですが,まずは,PowerShell ISEを一般ユーザーの権限で実行します。管理者権限で実行する必要はありません。何をやっているか意味が分かる方であれば,もちろん管理者で実行しても問題ないです。

PowerShell ISEを一般ユーザーの権限で実行

PowerShell ISEを一般ユーザーの権限で実行

そして,以下のPowerShellをコピペして実行してください。緑色の三角アイコンが実行ボタンです。

$script = '$signature = @"
[DllImport("powrprof.dll")]
public static extern bool SetSuspendState(bool Hibernate,bool ForceCritical,bool DisableWakeEvent);
"@
$func = Add-Type -memberDefinition $signature -namespace "Win32Functions" -name "SetSuspendStateFunction" -passThru
$func::SetSuspendState($false,$true,$false)'

$bytes = [System.Text.Encoding]::Unicode.GetBytes($script)
$encodedCommand = [Convert]::ToBase64String($bytes)

$action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-encodedCommand $encodedCommand"

$trigger = New-ScheduledTaskTrigger -Daily -DaysInterval 1 -At 08:09
Register-ScheduledTask -TaskName "Sleep" -Action $action -Trigger $trigger -Force

$action = New-ScheduledTaskAction -Execute "cmd.exe" -Argument "/c echo hello"
$settings = New-ScheduledTaskSettingsSet -WakeToRun
$trigger = New-ScheduledTaskTrigger -Daily -DaysInterval 1 -At 08:12
Register-ScheduledTask -TaskName "WakeUp" -Action $action -Settings $settings -Trigger $trigger -Force
PowerShellをコピペして実行

PowerShellをコピペして実行

 

すると,タスクスケジューラの画面に,下図のように2つのタスクが登録されますので,これらのタスクをダブルクリックして,実行日時や頻度を好みに調整していきます。平日だけにするのか,どんなプログラムを起動時に実行するのか,などです。

2つのタスクが登録される

2つのタスクが登録される

 

ちなみに,Sleepタスクの下図の設定において,-encodedCommandの後に,エンコードされた長いパラメーターが付されていることを確認してください。

encodedCommandの後に,エンコードされた長いパラメーターが付されていることを確認する

encodedCommandの後に,エンコードされた長いパラメーターが付されていることを確認する

もし,上図のようにパラメーターが空っぽであれば,PowerShellの実行権限が不十分ですので,PowerShell ISEを管理者で立ち上げて実行するなど試してみてください。その場合,タスクスケジューラも管理者として実行する必要があるかもしれません。

もし,上述のPowerShellコマンドが何をやっているのか知りたい方は,以下のMicrosoftのページを参照してください。SetSuspendStateの設定方法が肝心です。

Application.SetSuspendState(PowerState, Boolean, Boolean) メソッド (System.Windows.Forms)
システムを中断または休止状態にするか、システムが中断または休止状態になるよう要求します。Suspends or hibernates the system, or requests that the system be suspended or hibernated.

WakeUpタスクの中では,スリープ解除のために「コマンドプロンプトを一瞬立ち上げてhelloと出力する」というタスクを仕込んであります。ですので,ユーザーの目に触れることはありません。

もちろん,このWakeUpタスクを編集して,「ブラウザを立ち上げ特定のURLを表示する」といったタスクに置き換えても問題ありません。

スリープ解除をテストする際に十分な待ち時間を設ける

これも結構ハマるポイントだと思います。

例えば,スリープ解除を9:00に設定したとします。すると,実際にスリープ解除が実行されて,コンピューターが立ち上がり始めるのは,9時00分30秒ぐらいだったりします。スペックによっては,15秒ぐらいのこともありますし,30秒以上かかることもあります。

それで,テストする際には,指定時刻を過ぎたからと言って,すぐに諦めて手動でスリープ解除してしまうのではなく,30秒ぐらい経ってからスリープ解除動作が始まることもあると思っていてください。

タスクスケジューラでスリープ解除できるようになったがモニタが点かない

次に直面しがちなのは,タスクスケジューラでスリープ解除できるようになったものの,モニタが点かないという症状です。

これも,かなり色々な方法を試しましたが,最終的には,WakeDisp2というフリーソフトを使うのがベストという結論になりました。

PowerShellでマウス入力やキー入力を疑似的にスケジュールしてみたりもしたのですが,それはモニタの点灯に影響を与えることができませんでした。

常駐型のフリーソフトを入れるなど気持ちが悪いので,何とかWindows 10のネイティブな機能で実現できないか格闘しましたが,振り返ってみれば,さっさとWakeDisp2入れておけばよかったという感想です。

WakeDisp2は,以下のページからダウンロードできます。
https://ux.getuploader.com/open2ch1/download/716

ダウンロードボタンが小さくて分かりづらいので,図示しておきます。
ダウンロードボタンをクリックした後,ウイルススキャンが走るので,その後もう一度,ダウンロードボタンを押す必要があります。

ダウンロードボタンが小さくて分かりづらい

ダウンロードボタンが小さくて分かりづらい

 

これを,適当な場所に置き,実行します。設定等は一切不要です。
タスクトレイに常駐するソフトですが,インストールは不要ですし,特に悪影響を心配するような挙動はありませんので,問題ないです。

これで,タスクスケジューラからスリープ解除した際に,モニタが点くようになりました。

WakeUpタスクがずっと「実行中」になってしまう場合

これは余談ですが,例えば,WakeUpタスクにおいて,ブラウザを立ち上げる等のプログラムの開始をスケジュールしたとします。

その場合,スリープ解除してブラウザは立ち上がったものの,タスクスケジューラ内において,タスクのステータスがずっと「実行中」になってしまうということがあります。

これは,コマンドの指定の仕方で回避することができます。

まず,以下の1行をコピペしてテキストファイルに貼り付け,OpenChrome.batなどと名前を付けて保存します。最後の行にexitとか書かなくても大丈夫です。

start "" "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" "https://www.msn.com/"

このコマンドの意味は「コマンドプロンプトを空白のタイトルで立ち上げ,続くコマンドを実行する」という命令です。

そして,そのbatファイルを実行するというタスクを設定します。

バッチファイルを実行するタスクにする

バッチファイルを実行するタスクにする

こうすることで,「実行中」というステータスのままになってしまうことを避けられるかもしれません。

もちろん,普通にプログラムを実行するだけで問題ない場合も多々あります。それで,タスクが「実行中」のままになってしまって困っている場合に,一つの方法として試してみてください。

 

以上,Windows 10において,タスクスケジューラでスリープやスリープ解除を設定するためのハマりどころと,その回避策でした。

悩んでいる方の参考になればと思います。他にも個々の状況に応じて乗り越えるべき課題があると思いますが,質問があればコメント欄にどうぞ。

Amazon売れ筋No.1チェアが4000円引きで2万以下[腰痛対策]

現時点(2020/7/3)で,Amazonのゲーミングチェア売れ筋No.1のチェアが4000円引きで売られています。

ゲーミングと名付けられていますが,要するに長時間座っていても疲れにくいことを目的としたチェアですので,オフィスワーカーにもピッタリかと。

このクオリティで2万を切るというのは,価格崩壊感あり。

しかもオットマン(足置き)付きのモデルなので,少し休憩したい際に,ほぼフラットに倒しつつ足を延ばして仮眠できます。

リモートワーク時代に入って,自宅の貧弱な椅子による腰痛が大きな問題に。

それで,こういうホールド感のある,また腰・首サポートのあるチェアを使って,体への負担を軽減しましょう。腰は一生ものですので,将来を考えると,これで2万は良い投資。

両サイドからの適度な締まりによって,集中力も上がり,一日の生産性が高まる効果も期待できそう。

リモートワーク時代で爆売れ中のようですので,気になる方は早めにポチっておくのが良いかと。今なら翌日届くようです。

Windows 10
MacRuby

コメント