【Powershell】 Excelのプロセスが残る


Excelを閉じた後にプロセスが残るについて


powershellではexcelを簡単に操作することができます。

簡単に使い方を説明すると

#excelオブジェクトを開く
$excel = New-Object -ComObject Excel.Application
#excel非表示
$excel.Visible = $false
#ブックを開く
$excelFile = $excel.Workbooks.Open("ファイルパス")
# Excelのシート
$sheet = $excel.Worksheets.Item("シート名またはシート番号")
#セルに値を編集
$cell= $sheet.Cells.Item(1,1) = "10"
#ブックを閉じる
$excelFile.Close()
#excelを閉じる
$excel.Quit()

みたいな感じで使用できます。

powershellexcelを操作する記事はたくさんあので、興味がある方は検索してみてください。

ここで問題なのは$excel.Quit()excelを閉じたにも関わらず。
タスクマネージャーを確認するとexcelのプロセスが残ってしまうことです。

nullを代入するとかガベージコレクションを最後に呼ぶとかいろいろ試した結果

[void][System.Runtime.InteropServices.Marshal]::FinalReleaseComObject($excel)

でプロセスを開放することができました。

先ほどのソースに追加すると

#excelオブジェクトを開く
$excel = New-Object -ComObject Excel.Application
#excel非表示
$excel.Visible = $false
#ブックを開く
$excelFile = $excel.Workbooks.Open("ファイルパス")
# Excelのシート
$sheet = $excel.Worksheets.Item("シート名またはシート番号")
#セルに値を編集
$cell= $sheet.Cells.Item(1,1) = "10"
#ブックを閉じる
$excelFile.Close()
#excelを閉じる
$excel.Quit()
#comオブジェクトを開放
[void][System.Runtime.InteropServices.Marshal]::FinalReleaseComObject($sheet)
[void][System.Runtime.InteropServices.Marshal]::FinalReleaseComObject($excel)

[void]にしなくてもいいですが、コンソールに結果が返ります。
1とか文字が出力される。
voidにしなくてもとくに処理には影響ないと思います。

powershellは開放する順番は関係なく開放してくれますが、.Netだと
comオブジェクトの開放に順番があるようです。
excelでいうと セル → シート → excel の順番でないと
プロセスが残ってしまうようです。

powershellの曖昧なとこいいよね!!!

また、プロセスの開放に時間がかかることがあるので、
処理終了後、タスクマネージャーでExcel.exeをしばらく見てみてください。

下記サイト参考にさせていただきました。ありがとうございます。
mtgpowershell.blogspot.jp