社内SEの話

日々起きたことの記録用

【PowerShell】Excel操作処理後にExcelのプロセスが残る

PowerShellExcel操作して保存して終了してもプロセスが残ってしまいます。

これはExcel操作をするためにCOMオブジェクトを使うのですが、COMオブジェクトで使った変数は必ず開放してあげないとプロセスが残ってしまいます。

サンプル(プロセスが残る)

下記のサンプルではプロセスが残ってしまいます。

PowerShellExcel操作して保存して終了してもプロセスが残ってしまいます。

これはExcel操作をするためにCOMオブジェクトを使うのですが、COMオブジェクトで使った変数は必ず開放してあげないとプロセスが残ってしまいます。

サンプル(プロセスが残る)

下記のサンプルではプロセスが残ってしまいます。

$excel = New-Object -ComObject Excel.Application

$book = $excel.Workbooks.Open("D:PowerShelltestexcel.xlsx")

$sheet = $book.Sheets(1)

$sheet.cells.item(1,1).value() = "Hello World"

$book.save()

$excel.Quit()

[GC]::Collect()

確認の為実行してみます。

処理が終わってもプロセスが残っているのが確認できます。

結果を確認してみると、値が入っていません。

保存処理がされていないため、操作結果がないものと思われます。

【対応策1】

Excelを終了させる際に下記のプログラムを使って変数を開放させます

[System.Runtime.Interopservices.Marshal]::ReleaseComObject($excel) | Out-Null

[System.Runtime.Interopservices.Marshal]::ReleaseComObject($book) | Out-Null

[System.Runtime.Interopservices.Marshal]::ReleaseComObject($sheet) | Out-Null

サンプル(プロセスが残らない)

$excel = New-Object -ComObject Excel.Application

$book = $excel.Workbooks.Open("D:PowerShelltestexcel.xlsx")

$sheet = $book.Sheets(1)

$sheet.cells.item(1,1).value() = "Hello World"

$book.save()

$excel.Quit()

[System.Runtime.Interopservices.Marshal]::ReleaseComObject($excel) | Out-Null

[System.Runtime.Interopservices.Marshal]::ReleaseComObject($book) | Out-Null

[System.Runtime.Interopservices.Marshal]::ReleaseComObject($sheet) | Out-Null

[GC]::Collect()

【対応策2】

Excelを終了させる際に下記のプログラムを使って変数を開放させます

$excel = $null

$book = $null

$sheet = $nul

サンプル(プロセスが残らない)

$excel = New-Object -ComObject Excel.Application

$book = $excel.Workbooks.Open("D:PowerShelltestexcel.xlsx")

$sheet = $book.Sheets(1)

$sheet.cells.item(1,1).value() = "Hello World"

$book.save()

$excel.Quit()

$excel = $null

$book = $null

$sheet = $nul

[GC]::Collect()

終わりに

MarshalとNullの違いについて調べると処理の違いはあるものの、どちらも終了時プロセスは残りませんでした。

どちらもコード量は多くないので、ご自身の環境で確実にプロセスが終了する方を採用すればいいと思います。