2012/01/13

コンピュータの再起動はRestart-Computerコマンドレット、シャットダウンはStop-Computerコマンドレットを使えばできますが、(休止状態ではなく)スリープはどうやるんだろう?と疑問に思い調査しました。

  • COMコンポーネントのShell.ApplicationのSuspendメソッドを使う方法:
    少なくともうちのWin7環境では使えませんでした(何も起こらない)。
  • shutdown.exeを使う方法:
    /hオプションを使えば休止状態にはできるが、スリープはできない模様。
  • rundll32.exe powrprof.dll,SetSuspendStateを使う方法:
    ハイブリッドスリープが有効である場合は休止状態になる。ちなみにネットでたまにみかける”rundll32.exe powrprof.dll,SetSuspendState Sleep”でスリープするというのは嘘tipsです。
    参照:rundll32.exe powrprof.dll,SetSuspendState Sleepって大嘘は誰が言い出したん - xcaqhbajのメモ
  • WMIのWin32_OperatingSystemのWin32Shutdownメソッドを使う方法:
    シャットダウン、再起動、ログオフはできますがスリープや休止状態はできないようです。

というわけであまり簡単にはいかないようです。

幸いPowerShell 2.0からはAdd-TypeコマンドレットによりC#やVBを介してP/Invokeができますので、これを利用してスリープを行うWin32APIを呼び出すことにしました。

$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,$false,$false) 

powrprof.dllに含まれるSetSuspendState関数をP/Invokeで呼び出してやります。引数のHibernateはTrueを指定すると休止状態、Falseを指定するとスリープになります。今回はスリープしたいので$falseを渡してやります。

あとで知ったのですがSystem.Windows.Forms.Application.SetSuspendState メソッドを使うのでもいいですね。こちらの場合はAdd-TypeコマンドレットでSystem.Windows.Formsを読み込むと利用できるかと思います。

Add-TypeコマンドレットのおかげでPowerShellからWin32APIを簡単に呼べるようになり、○○はWin32APIを使わないといけないから諦めよう、ということがなくなりました。WSH時代に比べると良くなったなーと思います。本当はなるべくならWin32APIを直接は使わずに片づけたいところですけども。


古い記事へ | 新しい記事へ


プライバシーポリシー

Twitter

Books