11

1 つの PowerShell スクリプトに小さなユーティリティ関数があります。

function Unzip-File{
    param(
        [Parameter(Mandatory=$true)]
        [string]$ZipFile,
        [Parameter(Mandatory=$true)]
        [string]$Path
    )

    $shell=New-Object -ComObject shell.application

    $zip = $shell.namespace($ZipFile)
    $target = $shell.NameSpace($Path)
    $target.CopyHere($zip.Items())
}

スクリプト内の COM オブジェクトをクリーンアップする必要がありますか? または、PowerShell は COM オブジェクトを自動的にガベージするのに十分スマートですか?

COMオブジェクトを取り除く(一度だけ)を読んで、やみくもに適用しました:

[System.Runtime.Interopservices.Marshal]::ReleaseComObject($zip)
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($target)
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($shell)

しかし、これが必要かどうかはわかりません。

ローカル関数で COM オブジェクトを使用する正しいパターンは何ですか?

4

2 に答える 2

10

Usually I use this function:

function Release-Ref ($ref) {

[System.Runtime.InteropServices.Marshal]::ReleaseComObject([System.__ComObject]$ref) | out-null
[System.GC]::Collect()
[System.GC]::WaitForPendingFinalizers()

}

because I've noted that my comobject always stay alive, I think Powershell 2.0 is not able to remove comobject no more used.

[System.Runtime.InteropServices.Marshal]::ReleaseComObject( $ref )

(see here) return the new value of the reference count of the RCW associated with object. This value is typically zero since the RCW keeps just one reference to the wrapped COM object regardless of the number of managed clients calling it. I've noted that for shell.application you need to call it until this value becomes 0.

To test if all references are released you can try, when value is 0, to read the value of $shell: it returns an error..

于 2013-09-26T13:43:23.303 に答える