« | »

2014年5月14日

どんな環境でも確実にスリープする「スリープる」を作った/APIスリープで休止する端末でスリープのショートカットを作る

ありがたい事に、いつも使わなくなったりお古になったPCやらPC用品やらをプレゼントしてくれる友人にWindows8のタブレット端末をいただいた。
windows8が入ったDellのlatitude10なるタブレットである。

今まで仕事ではWindows8をちょこちょこ使う機会があったものの、ちゃんと使うのはじめてである。

世間でWindows8は使いにくいと評判だけど、いやいやめっちゃ使いやすいですやん。

「タブレットを買うと家庭での生活が一変する」と言っていた友人がいたけどまさにその通り。
普段はタッチパネルをメインに使っていても、キーボードとマウスをつなげば普通のパソコンとして使えるので、今までつかっていたIBMのThinkpadはもうほとんど起動されず、デスクトップでバリバリ作業するまでもない事はすべてタブレットで行っている。

スリープしておけばほとんど電力を消費しない割りにすぐに複電するので、使わない時はちょくちょくスリープするようにしたいのだが、
通常操作でスリープしようとすると画面右をスワイプして、チャームを出してから、設定→電源→スリープ
とちょっとまどろっこしい。

ってことで、スリープするためのショートカットを作ろうと思ったのだが、一般的なWindows内のシステム関数を使う、

rundll32.exe powrprof.dll,SetSuspendState

へのショートカットだと、他のPCではちゃんとスリープするのに、latitude10だけは休止状態になってしまう。

他にもいろいろとスリープさせる方法を探したり試したりしたのだが、このlatitude10ではWindows8.1にアップグレードしたせいか、どうしても休止状態になってしまう。

で、スリープのショートカットがなければ作ればいいじゃない!
ということで、WSHのスクリプトを書いてみた。
機能としてはシャットダウンメニューを出してプルダウンメニューからスリープを選んでエンターキーを押しているだけw
具体的にはシャットダウンのメニュー画面で↑キーを八回押して、デフォルトでどのメニューを選択していても一番上のメニューを選んだ状態にしてから、↓キーを特定回押して「スリープ」を選んでエンターキーを押すとw
謎のAPI呼び出したりやらブラックボックスな内部関数叩かずにOSの標準メニューを操作しているので、動作は間違いない。
ただし時々間違えてシャットダウンしたり再起動したりするのはご愛嬌w
なので、一応起動時にスリープするか聞いて、「はい」を押すか、3秒放置すればスリープ状態に移行するようにワンクッション置いてみた。
更に、Windowsのバージョンによってスリープまでのメニューの構造が違うのでOSによって↓を押す回数を変えるようにした。
以下のコードをコピーしてメモ帳に貼り付け「sleeple.vbs」とか適当な名前で保存すればOK。ダブルクリックすれば動作するですぞ。

'sleeple Ver1.0
'by 土偶 http://www.dogustat.com/?p=7217
'windows8をスリープする(他バージョンのwindowsでも可)
'
set Shell = CreateObject("Shell.Application")
set WshShell = WScript.CreateObject("WScript.Shell")

Answer = WshShell.Popup("スリープ?",3, "スリープる", 36 ) 'タイムアウト3秒
if ( Answer <> 6 ) and ( Answer <> -1 )then Wscript.quit
Count= GetOSVersion()
Shell.ShutdownWindows()
Do Until WshShell.AppActivate("Windows のシャットダウン")	 'ダイアログが出るまでループしつつ待つ
	 WScript.sleep 100	 '100ミリ秒待つ
Loop

For x =1 To 8 '↑を八回押す
	WshShell.SendKeys "{UP}"
Next

For x = 1 To Count '↓をCount回押す
	WshShell.SendKeys "{DOWN}"
Next

WshShell.SendKeys "{ENTER}"	'エンターを押す

Function GetOSVersion()
	Dim obj,colTarget,objRow,str,aData,nData,I

	Set obj = GetObject("winmgmts:\\.\root\cimv2")
	Set colTarget = obj.ExecQuery( "select * from Win32_OperatingSystem" )
	For Each objRow in colTarget
		str = objRow.Version
	Next
	aData = Split( str, "." )
	For I = 0 to Ubound( aData )
		if I > 1 then
			Exit For
		end if
		if I > 0 then
			nTarget = nTarget & "."
		end if
		nTarget = nTarget & aData(I)
	Next

	Ver = CDbl( nTarget )
	'Msgbox(Ver)

	Select Case Ver
	Case "5.1"	'XPの場合↓3回
		Count = 3
	Case "6"	'vistaの場合↓3回
		Count = 3
	Case "6.1"	'7の場合↓3回
		Count = 3
	Case "6.2"	'8の場合↓2回
		Count = 2
	Case "6.3"	'8.1の場合↓2回
		Count = 2
	Case Else
		Count = 2
	End Select
	GetOSVersion = Count
End Function

例のごとくZIPでよこせという方にはexe化したものを上げておく、
名づけて「スリープる」 ダウンロードはこちら [sleeple.zip]

アイコンも無駄に可愛いくしたったw

名前とアイコンまでつけた割には、動きゃぁ良いんだよ!とVBSをexe化しただけのなんちゃって実行ファイルやけど、この実行ファイルをWindow8のスタートパネルにピン止めすればスリープが捗るぞ。

しかし、これをexe化して実行してみたとたんにあるアンチウィルスソフトウェアに未知のマルウェアとして検出されたのでびっくりだよ!
ええっ!?私は知らんうちにウィルス作ってたのかい!?

節子それウィルスやない中身はただのvbスクリプトやー
とは思いつつも、でもまぁ確かに特定のAPI叩いてキーコードを勝手に送ってるねんから動きとしては限りなくトロイの木馬に近いwしかも端末スリープさせてるしw

しかし、まぁ、誤検知されたのは良いとしても、検出時にアンチウィルスソフトの「未知のウィルスの検体をサーバーに送りますか?」的な質問に思わず「はい」を押してしまったのは不覚であった。
私の作った「スリープる」は即刻アンチウィルスソフトウェアに捕獲されてその会社のサーバーに転送されてしまったのだ。

おーいちょっと待ってくれーーー違うねんーあー自分の作ったファイルやのにー
署名と配布先URL入りでトロイの木馬作るわけないやろーーあほー

「スリープる」はその会社のラボに囚われ、丸裸にされて分解されて隅々まで調べられ、あんなことこんなことされて尋問されているに違いない。
そしてラボでは多分「何や中身はただの無害なVBスクリプトやんけ」とか言われているに違いない。
私のバカバカ~「スリープる」いろんな意味でごめんよ~~

ドナドナド~ナ~ド~ナ~TCP/IPパケットがゆ~れる~♪

  

Trackback URL

Comment & Trackback

No comments.

Comment feed

Comment





XHTML: You can use these tags:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>