Best way to check if an PowerShell Object exist?
我正在寻找检查COM对象是否存在的最佳方法。
这是我的代码;我想改进最后一行:
1 2 3 4 5 | $ie = New-Object -ComObject InternetExplorer.Application $ie.Navigate("http://www.stackoverflow.com") $ie.Visible = $true $ie -ne $null #Are there better options? |
我会坚持使用
你也可以这样做
1 2 3 | if ($ie) { # Do Something if $ie is not null } |
在您的特定示例中,可能根本不需要执行任何检查。有没有可能
只有在下面这样的代码中,我们需要进行一些检查(最好与$null进行显式比较):
1 2 3 4 5 6 7 8 9 10 11 12 13 | # we just try to get a new object $ie = $null try { $ie = New-Object -ComObject InternetExplorer.Application } catch { Write-Warning $_ } # check and continuation if ($ie -ne $null) { ... } |
所有这些答案都没有突出显示的是,将值与$null进行比较时,必须将$null放在左侧,否则与集合类型值进行比较时可能会遇到问题。请参阅:https://github.com/nightroman/powershelltraps/blob/master/basic/comparison-operators-with-collections/looks-like-object-is-null.ps1
1 2 3 4 | $value = @(1, $null, 2, $null) if ($value -eq $null) { Write-Host"$value is $null" } |
上面的块被(不幸地)执行。更有趣的是,在PowerShell中,$值可以是$null,也可以不是$null:
1 2 3 4 | $value = @(1, $null, 2, $null) if (($value -eq $null) -and ($value -ne $null)) { Write-Host"$value is both $null and not $null" } |
因此,重要的是将$null放在左侧,以使这些比较能够与集合一起工作:
1 2 3 4 | $value = @(1, $null, 2, $null) if (($null -eq $value) -and ($null -ne $value)) { Write-Host"$value is both $null and not $null" } |
我想这又显示了PowerShell的威力!
对于任何空值,使用-is运算符进行类型检查时返回false。在大多数情况下,如果不是全部,$value-is[system.object]对于任何可能的非空值都将为true。(在所有情况下,任何空值都将为假。)
如果不是一个对象,我的值就是零。
如果您像我一样,您在这里登陆,试图找到一种方法来判断您的PowerShell变量是否是这种不存在的特殊风格:
COM object that has been separated from its underlying RCW cannot be
used.
下面是一些适用于我的代码:
1 2 3 4 5 | function Count-RCW([__ComObject]$ComObj){ try{$iuk = [System.Runtime.InteropServices.Marshal]::GetIUnknownForObject($ComObj)} catch{return 0} return [System.Runtime.InteropServices.Marshal]::Release($iuk)-1 } |
示例用法:
1 | if((Count-RCW $ExcelApp) -gt 0){[System.Runtime.InteropServices.Marshal]::FinalReleaseComObject($ExcelApp)} |
从其他人更好的答案中混合而成:
- 在C中使用COM互操作时的RCW和引用计数#
- RCW参考计数规则!=COM引用计数规则
- "已与其基础RCW分离的COM对象不能与.NET 4.0一起使用"
还有一些很酷的事情要知道:
- 无法使用已与其基础RCW分离的COM对象
- 定制排列
- 高级COM互操作性
我也有同样的问题。这个解决方案对我有效。
1 2 3 4 5 6 | $Word = $null $Word = [System.Runtime.InteropServices.Marshal]::GetActiveObject('word.application') if ($Word -eq $null) { $Word = new-object -ComObject word.application } |
https://msdn.microsoft.com/de-de/library/system.runtime.interopservices.marshal.getActiveObject(v=vs.110).aspx