2013-09-26 1 views
4

내가 한 PowerShell 스크립트에서 작은 유틸리티 기능이 있습니다PowerShell을 릴리스 COM 개체

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 개체를 가비지 처리 할만큼 똑똑합니까?

제가 적용 맹목적으로Getting Rid of a COM Object (Once and For All)을 읽었습니다 :

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

하지만이 필요한 경우 확실하지 않다.

로컬 함수에서 COM 개체를 사용하는 올바른 패턴은 무엇입니까? 나는 나의하여 ComObject 항상 살아있어 주목했기 때문에

function Release-Ref ($ref) { 

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

} 

, 나는 파워 쉘 2.0은 더 이상 사용하여 ComObject를 제거 할 수 없습니다 생각 :

+0

내가 아는 기사가 맞을 것으로 생각합니다. 변수에 대한 다른 참조를 해제하기 위해'Remove-Variable'의 주석을 조금 읽은 다음 나머지는 GC가 처리합니다. 당신의 객체가'Dispose()'메소드를 가지고 있다면 당신은 그것을 호출하기를 원할지도 모른다. – alroc

답변

1

보통 나는이 기능을 사용합니다.

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

(here 참조) 개체와 관련된 RCW의 참조 횟수의 새로운 값을 반환한다. RCW는 호출 한 관리되는 클라이언트의 수에 관계없이 랩핑 된 COM 개체에 대한 하나의 참조 만 유지하므로이 값은 일반적으로 0입니다. 그것이를 반환 나는 shell.application 당신이 값이 $ 쉘의 값을 읽고, 0 일 때이 값이, 모든 참조 당신이 시도 할 수 있습니다 출시되는 0

테스트 될 때까지 호출 할 필요가 있다고 지적했습니다 오류 ..

+0

내 개체가 제대로 지워지는 경우 "모니터링"할 수 있습니까? –

+0

보통 저는 사무 자동화를 사용하고 더 이상 존재하지 않지만 shell.application이있는 상대 프로세스 (즉, excel.exe)를 봅니다. 작동하는데 의심의 여지가 있습니다 ... –

+1

'ReleaseComObject'는 키. 나는 또한 두 개의 다른 라인이 필수는 아니라고 생각한다. C#을 사용하면 결정할 때 GC를 작동시키는 것이 더 좋습니다. 추신 : 나는이 조언을 PS에서 지킬 것이다. –