Get-Processの結果をシートに設定してみる。
$excel = New-Object -Com Excel.Application $excelBook = $excel.Workbooks.Add() $excelSheet = $excelBook.WorkSheets.Item(1) $excelCells = $excelSheet.Cells Get-Process | %{$i = 1}{ $excelCells.Item($i,1) = $_.Id $excelCells.Item($i,2) = $_.ProcessName $i++ } $xlOpenXMLWorkbook = 51 #Excel2007形式 $OutputPath = "D:\test.xlsx" $excelBook.SaveAs($OutputPath,$xlOpenXMLWorkbook) $excel.Quit() |
Foreach-Object(Aliasは%)はスクリプトブロックの配列が指定できる。
%{前処理}{ループ処理}{後処理}の形式。
Excelの保存形式はEnumの値を指定する。Excel2007形式は「51」。
これで問題なさそうだが、Comオブジェクトは参照を解放しないとプロセスが残ってしまう。
(ps Excelで確認できる)
乱暴に、kill –name Excel とする方法もあるが、もう少しスマートに。(まっとうに)
[System.Runtime.InteropServices.Marshal]::FinalReleaseComObject($excel) |
とすると開放してくれるようだ。
これを各変数に対して行うと、
foreach($obj in $excel,$excelBook,$excelSheet,$excelCells){ [System.Runtime.InteropServices.Marshal]::FinalReleaseComObject($obj) } |
もう少し汎用的にしてみる。
Get-Variable excel* | %{ [System.Runtime.InteropServices.Marshal]::FinalReleaseComObject($_.value) } |
戻り値がうっとうしいときは、
Get-Variable excel* | %{ [System.Runtime.InteropServices.Marshal]::FinalReleaseComObject($_.value) | Out-Null } |
voidにキャストしても良い。
Get-Variable excel* | %{ [void][System.Runtime.InteropServices.Marshal]::FinalReleaseComObject($_.value) } |
0 件のコメント:
コメントを投稿