はじめに
突然ですが、皆さんはPCをシャットダウンをするのを忘れたまま、出かけてしまったりすることはないでしょうか?僕はあります。
そこで僕は考えました...どうすれば消し忘れないのかと...
そして、自動で一定時間放っておかれたらシャットダウンしちゃえばいいのではないかという結論に至りました。
※Windows7(32bit)で動作確認しております。
さっそく作ってみる
今回は、C言語+WindowsAPIを用いて作ってみます。
まず、[一定時間放っておかれたら]という点ですが、これはスクリーンセーバーを用いれば楽なのではないかと思いつきました。
つまり、
スクリーンセーバーが起動
↓
シャットダウンさせる
みたいな感じですね。
というわけでまずは、スクリーンセーバーをWindowsAPIを使って書いていきます。
調べてみたところ、スクリーンセーバーを使うためには、
scrnsave.hをincludeし、
ScreenSaverProc関数、ScreenSaverConfigureDialog関数、RegisterDialogClasses関数を用いればよいようです。
というわけで書いてみました
#include <windows.h>
#include <scrnsave.h>
#pragma comment(lib,"ScrnSave.lib")
#pragma comment(lib,"Comctl32.lib")
LRESULT WINAPI ScreenSaverProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
HANDLE token;
LUID id;
TOKEN_PRIVILEGES token_p;
switch (msg) {
case WM_CREATE:
OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token);
LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &(token_p.Privileges[0].Luid));
token_p.PrivilegeCount = 1;
token_p.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(token, FALSE, &token_p, 0, NULL, NULL);
ExitWindowsEx(EWX_FORCE | EWX_SHUTDOWN, 0);
break;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
default: break;
}
return DefScreenSaverProc(hWnd, msg, wParam, lParam);
}
BOOL WINAPI ScreenSaverConfigureDialog(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) {
return TRUE;
}
BOOL WINAPI RegisterDialogClasses(HANDLE hInst) {
return TRUE;
}
以上です。
WM_CREATE内のごちゃごちゃしたやつは、シャットダウンするために必要なExitWindowsEx関数を呼び出すためにSE_SHUTDOWN_NAME特権を有効にしています。
実行結果
ちゃんとシャットダウンできました。
拡張子をsrcに変えてあとは、時間を設定すれば使うことができる(はず)です。
追記
これじゃ設定時にシャットダウンしてしまい設定できませんでした...
起動した直後に若干待機させるなどして設定用の時間を設けなければいけないかもしれません。