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を直接は使わずに片づけたいところですけども。

2007/01/15

スクリプト センターの新着記事にこんなのが。

VBScript からも .NET Framework のクラスを利用できる?!
NET Framework のクラスは VBScript からアクセスできないと皆さん思っていませんか? 後悔する前にこの記事を読みましょう!

System.Collections.ArrayListなんかを普通にCreateObjectして使えるんですねー。

しらんかったー!すげー!

たしかにProgIDがレジストリに登録されてるから、使えるような気はしてましたが、まさか本当に使えるとは。

これってどういう仕組みなんだろう?どのクラスが使えてどのクラスがだめかは筆者も調査中とのことですが、相当いろんなことができるんじゃないでしょうか。

少なくともCOMコンポーネントにはコンストラクタがない(ですよね?)のでコンストラクタが必須のクラスは駄目でしょうね。

まだまだWSHいけるんじゃないですか?PowerShellもいいですけどWSHも使いましょう。

元記事:http://blogs.wankuma.com/mutaguchi/archive/2007/01/15/56349.aspx

2006/12/09

元記事はhttp://winscript.s41.xrea.com/mt/archives/2005/09/post_5.htmlです。

クリップボードを扱う.NET Frameworkのクラスに、Clipboardクラスがあります。そのSetDataObjectメソッドを使うとクリップボードにテキストデータを格納できる、はずです。が、

[void] [Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") 
[System.Windows.Forms.Clipboard]::SetDataObject("あああ")

のようなスクリプトを実行すると、

Exception calling "SetDataObject" with "1" argument(s): "OLE が呼び出される前に、現在のスレッドが Single Thread Apartment (STA) モードに設定されていなければなりません。Main 関数に STAThreadAttribute が設定されていることを確認してください。".

というエラーが出てしまいます。MSHでMain関数にSTAThreadAttributeを指定するにはどうすれば良いのでしょうか? ちなみに

[System.Threading.Thread]::CurrentThread.ApartmentState = 
[System.Threading.ApartmentState]::STA

のようにしてもSTAにはなってくれませんでした。

クリップボードアクセスは、newpopsさんが提案されている、IEのCOMコンポーネントを使う方法で可能になります。

PowerShell Memo - 文字列をクリップボードにコピーする
http://d.hatena.ne.jp/newpops/20061104/p1

元記事:http://blogs.wankuma.com/mutaguchi/archive/2006/12/09/49650.aspx

2006/07/14

元記事はhttp://winscript.s41.xrea.com/mt/archives/2005/09/com.htmlです。

PowerShellでは.NETのオブジェクトのほかに、COMのオブジェクトも呼び出すことができます。呼び出し方は$Fs = new-object -com Scripting.FileSystemObjectのようにします。

このサンプルは、深い階層に新しいフォルダを再帰的に作成していくスクリプトです。

function CreateFolderEx ($Path){
 $sParent=$Fs.GetParentFolderName($Path)
 if ($Fs.FolderExists($sParent) -And !$Fs.FolderExists($Path)) {
  [void]$Fs.CreateFolder($Path)
 } elseif ($Fs.FolderExists($Path)) {
 } else {
  CreateFolderEx($sParent)
  [void]$Fs.CreateFolder($Path)
 }
}
$Fs = new-object -com Scripting.FileSystemObject
CreateFolderEx "C:\test\test\aaaa\wwww\aaa" 

FolderExistsと($Path)の間にスペースを入れるとエラーになるのに注意です。(beta 2ではならなかったのに…)

function CreateFolderEx ($Path){

は、

function CreateFolderEx {
Param($Path)

と書くこともできますが、個人的にこちらの書き方は冗長じゃないかなあという気がします。betaとの互換性のために残されているだけかもしれません。

ちなみに、.NET FrameworkのSystem.IO.DirectoryInfoクラスを使うならこんな面倒なことは必要ありません。

$di = new-object System.IO.DirectoryInfo("C:\test\test\aaaa\wwww\aaa")
$di.Create()
元記事:http://blogs.wankuma.com/mutaguchi/archive/2006/07/14/32456.aspx


Copyright © 2005-2018 Daisuke Mutaguchi All rights reserved
mailto: mutaguchi at roy.hi-ho.ne.jp
プライバシーポリシー

Books

Twitter