更新ネタが溜まってるのですが、一向に更新せずにいますー。
今日は、牟田口先生の以下のエントリーの内容を見てみたり。
PowerShell Scripting Weblog - CD-ROMトレイを取り出せるPowerShell関数、「Dismount-CDDrive」作った
いくつか記事の内容では気になる点があったため、検証しました。
WMPlayer.OCXでのCD ROMの開閉
ここにも有りますが、
WMPlayer.OCXオブジェクトを使うと、Windows Media Player へのプログラムによるアクセスが可能になります。
Hey, Scripting Guy! .WMA ファイルの Title プロパティを変更する方法はありますか
さて、では示されていたコードを見てみます。
(New-Object -com WMPlayer.OCX.7).cdromCollection.Item(0).Eject()
至ってシンプルでキレイですねー。
New-Object -comでWMPalayer.OCX.7のオブジェクト生成してます。
※.7はWindows Media Player7 (XP以降搭載)を示すそうで…….8とかにしてもだめでしたw
※ただしWMPlayer.OCXだけで正常に動作します。.7の意図が読めないのですが…。
問題点
さて、CD ROMトレイの開閉は、以下で行います。
#CM ROMトレイを開ける
生成したオブジェクトで一回だけeject()メソッドを呼ぶ。
#CM ROMトレイを閉める
生成したオブジェクトで2回連続でeject()メソッドを呼ぶ。
先生の紹介では()でNew-Objectを囲むことで、ワンライナーでプロパティにアクセスしていますが…閉じられないんですね。
…そりゃそうですが。
#CD ROMトレイを開ける = 意図した通りCD ROMトレイが開きます。
(New-Object -com WMPlayer.OCX.7).cdromCollection.Item(0).Eject()
#CD ROMトレイを閉じる = 意図した通りCD ROMトレイが閉じません。
(New-Object -com WMPlayer.OCX.7).cdromCollection.Item(0).Eject()
(New-Object -com WMPlayer.OCX.7).cdromCollection.Item(0).Eject()
解決方法
WMPlayer.OCXを利用してCD Romトレイを開閉するには、生成したWMPlayer.OCXオブジェクトを介して以下のアクセスを要します。
よって、一度New-Objectで生成したオブジェクトを変数に保持して、その変数からeject()メソッドを呼ぶ必要があります。
つまり以下です。
※.7は入れてもいれなくてもWindows8では稼働しています。
#CD ROMトレイを開ける
function Eject-CDROM{
$wmplayer = New-Object -ComObject WMPlayer.OCX
$wmplayer.cdromCollection.Item(0).Eject()
}
Eject-CDROM
#CD ROMトレイを閉じる
function Close-CDROM{
$wmplayer = New-Object -ComObject WMPlayer.OCX
$wmplayer.cdromCollection.Item(0).Eject()
$wmplayer.cdromCollection.Item(0).Eject()
}
Close-CDROM
WMI ObjectでCD ROMの開閉
さて、上記のやり方だと、CD ROMトレイを指定しにくいですね…。
WMIを介したCD ROMドライブの確認は以下で行えます。
Get-WmiObject -Class Win32_CDROMDrive
シェルで、My Computerを指定するにはNameSpaceで17を指定します。
[22/Jan/2013追記]※なぜ17を指定するのかは、
この記事で紹介しています。
(New-Object -com Shell.Application).Namespace(17)
あとは、ParseNameにWMIで取得したドライブ名を指定します。
(New-Object -com Shell.Application).Namespace(17).ParseName("A:\")
最後に、InvokeVerbで信号を送ります。
(New-Object -com Shell.Application).Namespace(17).ParseName("A:\").InvokeVerb("Eject")
※Ejectで動きますが、動かない人は"E&ject"で試してください。
WMI Object経由で全CD ROM情報を取得して、COM経由でshellを介して全部CD ROMの開閉をすると以下になります。
※面倒なのでワンライナーにしました
(Get-WmiObject -Class Win32_CDROMDrive).Drive | %{(New-Object -com Shell.Application).Namespace(17).ParseName($_).InvokeVerb("Eject")}
ワンライナーにしましたが、これではNew-Objectしてるので閉めれなさそうですね…以下で。
$cdrom = Get-WmiObject -Class Win32_CDROMDrive
(Get-WmiObject -Class Win32_CDROMDrive).Drive | %{$cdrom.Namespace(17).ParseName($_).InvokeVerb("Eject")}
さて、色々試しましたがCD ROMトレイを開けることのは上手くいきますが、閉めることが出来ません。
どういうことか、トレイを指定してみますが…だめです。
$shell = new-object -com Shell.Application
$cd = $shell.Namespace(17).ParseName('A:\')
$cd.InvokeVerb("Eject")
$cd.InvokeVerb("Eject")
これは以下のフォーラムでも同様の問題を協議しており、残念ながらWindows Vista以降Ejectの仕様が変わり出来なくなったようです。
My Digital Life Forums > Coding Life > Scripting > Eject CD/DVD tray--simpe java script
winmm.dllを介したCD ROMの開閉
以下にサンプルがありますが……古いやり方ですしやめておきます。
PowerShell, CdAudioDoor Module
まとめ
牟田口先生の紹介されたWMPlayer.OCXを介したやり方がもっとも適してますね。
よってサンプルとしては、以下となります。
お好きにスイッチ追加して切り替えるなりどうぞ~。
#CD ROMトレイを開ける
function Eject-CDROM{
$wmplayer = New-Object -ComObject WMPlayer.OCX
$wmplayer.cdromCollection.Item(0).Eject()
}
Eject-CDROM
#CD ROMトレイを閉じる
function Close-CDROM{
$wmplayer = New-Object -ComObject WMPlayer.OCX
$wmplayer.cdromCollection.Item(0).Eject()
$wmplayer.cdromCollection.Item(0).Eject()
}
Close-CDROM
次回は、PowerShellでのWPF紹介です。