powershell中COM对象的垃圾收集

powershell中COM对象的垃圾收集,powershell,Powershell,我创建了以下函数,用于在脚本末尾清理对com对象的所有引用: function TrashCompactor ($reflist) { foreach ($ref in $Reflist){ [System.Runtime.InteropServices.Marshal]::ReleaseComObject([System.__ComObject]$ref) | out-null [Runtime.InteropServices.Marshal]::FinalReleaseComObj

我创建了以下函数,用于在脚本末尾清理对com对象的所有引用:

function TrashCompactor ($reflist) {

foreach ($ref in $Reflist){



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

[Runtime.InteropServices.Marshal]::FinalReleaseComObject($ref) | out-null

Remove-Variable $ref | out-null

}


[System.GC]::Collect()
[System.GC]::WaitForPendingFinalizers()

}

是否会像我预期的那样删除变量?包括[System.GC]:Collect是否有任何危害?

是,否。。。就像这样

[System.GC]::Collect()
[System.GC]::WaitForPendingFinalizers()
。。。这是一种常见的最佳做法

Windows将始终进行清理,但在您完成清理后,它将始终清理您的环境

如文件所述

通过跟踪变量使用情况来清理PowerShell环境

本问答和公认答案涵盖了

这正是你要问的,所以这个问题实际上是重复的

在我的示例中,我在变量中使用前缀,因此它们很容易找到,并且可以简单地进行全局清理

# Assign results to a variable and output to the screen using variable squeezing
($ponMyShell = New-Object -com "Wscript.Shell")
($ponDate = Get-Date)
($ponProcess = Get-Process |
    Select -First 3)

<#
# Results

Monday, 2 March, 2020 19:40:47

Handles  NPM(K)    PM(K)      WS(K)     CPU(s)     Id  SI ProcessName                                                                                                              
-------  ------    -----      -----     ------     --  -- -----------                                                                                                              
    186      14     2648       6800       0.14  15336   0 aesm_service                                                                                                             
    465      27    24300      34064       0.33  27612  22 ApplicationFrameHost                                                                                                     
    158       8     1928       4848       0.02  14268   0 AppVShNotify 

SpecialFolders     CurrentDirectory   
--------------     ----------------   
System.__ComObject C:\Windows\system32
#>

Get-Variable -Name 'pon*'
<#
# Results 

Name                           Value                                                                                                                                               
----                           -----                                                                                                                                               
ponDate                        02-Mar-20 19:46:59                                                                                                                                  
ponMyShell                     System.__ComObject                                                                                                                                  
ponProcess                     {System.Diagnostics.Process (aesm_service), System.Diagnostics.Process (ApplicationFrameHost), System.Diagnostics.Process (AppVShNotify)} 
#>


# Clear resource environment
Get-PSSession |
Remove-PSSession
<#
# Results

#>

[System.Runtime.InteropServices.Marshal]::
ReleaseComObject([System.__ComObject]$ponMyShell) |
Out-Null
<#
# Results

#>

[System.GC]::Collect()
[System.GC]::WaitForPendingFinalizers()
<#
# Results

#>

Get-Variable -Name 'pon*' |
ForEach { Get-Variable -Name $_ |
    Remove-Variable -Force }

# Validate clean-up
Get-Variable -Name 'pon*'

<#
# Results


#>
在局部变量(如$ref)上调用函数内部的Remove变量没有意义,因为当函数退出时,它将自动超出范围;除此之外,您必须传递变量ref的名称,而不是它的值$ref-ergo:Remove variable$ref;此外,Remove变量永远不会生成成功输出,所以将其管道化为Out Null是没有意义的。
# Assign results to a variable and output to the screen using variable squeezing
($ponMyShell = New-Object -com "Wscript.Shell")
($ponDate = Get-Date)
($ponProcess = Get-Process |
    Select -First 3)

<#
# Results

Monday, 2 March, 2020 19:40:47

Handles  NPM(K)    PM(K)      WS(K)     CPU(s)     Id  SI ProcessName                                                                                                              
-------  ------    -----      -----     ------     --  -- -----------                                                                                                              
    186      14     2648       6800       0.14  15336   0 aesm_service                                                                                                             
    465      27    24300      34064       0.33  27612  22 ApplicationFrameHost                                                                                                     
    158       8     1928       4848       0.02  14268   0 AppVShNotify 

SpecialFolders     CurrentDirectory   
--------------     ----------------   
System.__ComObject C:\Windows\system32
#>

Get-Variable -Name 'pon*'
<#
# Results 

Name                           Value                                                                                                                                               
----                           -----                                                                                                                                               
ponDate                        02-Mar-20 19:46:59                                                                                                                                  
ponMyShell                     System.__ComObject                                                                                                                                  
ponProcess                     {System.Diagnostics.Process (aesm_service), System.Diagnostics.Process (ApplicationFrameHost), System.Diagnostics.Process (AppVShNotify)} 
#>


# Clear resource environment
Get-PSSession |
Remove-PSSession
<#
# Results

#>

[System.Runtime.InteropServices.Marshal]::
ReleaseComObject([System.__ComObject]$ponMyShell) |
Out-Null
<#
# Results

#>

[System.GC]::Collect()
[System.GC]::WaitForPendingFinalizers()
<#
# Results

#>

Get-Variable -Name 'pon*' |
ForEach { Get-Variable -Name $_ |
    Remove-Variable -Force }

# Validate clean-up
Get-Variable -Name 'pon*'

<#
# Results


#>