检查PowerShell对象是否存在的最佳方法?


90

我正在寻找检查Com对象是否存在的最佳方法。

这是我的代码;我想改进最后一行:

$ie = New-Object -ComObject InternetExplorer.Application
$ie.Navigate("http://www.stackoverflow.com")
$ie.Visible = $true

$ie -ne $null #Are there better options?

Answers:


114

我要坚持的$null,因为比其他任何值检查''(空字符串), 0$false并且$null将通过支票:if ($ie) {...}


1
使用if($ val){...}更适合布尔值所有其他检查应使用if($ val -ne $ null){..}测试一下自己。TY @Keith Hill
Ilya Gurenko '19


16

在您的特定示例中,也许您根本不必执行任何检查。有可能New-Object返回null吗?我从未见过。如果出现问题,该命令应该失败,并且该示例中的其余代码将不执行。那么,为什么我们要进行所有检查呢?

仅在下面的代码中,我们需要进行一些检查(最好与$ null进行比较):

# 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) {
    ...
}

1
如果COM对象类型不存在,则New-Object将引发异常。但是我不知道它怎么能返回null。同样,仅忽略Exception然后测试是否为null是错误的形式。
JasonMArcher 2010年

@JasonMArcher:我完全同意最后一句话。但是,实际上,您希望我在演示示例中写些什么?此外,根据情况,即使此代码也可能很好。
罗曼·库兹敏

本质上,将所有使用$ ie的代码放在try {}中。这样,如果有异常,它将被跳过。
JasonMArcher 2010年

2
然后,当我们需要检查$ null时,该代码将不会显示情况。
罗曼·库兹敏

10

所有这些答案没有强调的是,在将值与$ null比较时,必须将$ null放在左侧,否则在与collection-type值进行比较时可能会遇到麻烦。参见:https : //github.com/nightroman/PowerShellTraps/blob/master/Basic/Comparison-operators-with-collections/looks-like-object-is-null.ps1

$value = @(1, $null, 2, $null)
if ($value -eq $null) {
    Write-Host "$value is $null"
}

上面的代码块(不幸的是)被执行。更有趣的是,在Powershell中,$ value既可以是$ null,也可以不是$ null:

$value = @(1, $null, 2, $null)
if (($value -eq $null) -and ($value -ne $null)) {
    Write-Host "$value is both $null and not $null"
}

因此,将$ null放在左侧非常重要,以使这些比较可与集合一起使用:

$value = @(1, $null, 2, $null)
if (($null -eq $value) -and ($null -ne $value)) {
    Write-Host "$value is both $null and not $null"
}

我想这再次显示了Powershell的强大功能!


惊讶的是,这个答案没有被更广泛地接受,因为它包含了放到左侧的关键细节$null
sonyisda1

1

使用-is运算符进行类型检查,对于任何空值都将返回false。在大多数情况下,如果不是全部,则对于任何可能的非null值,$ value -is [System.Object]将为true。(在所有情况下,任何空值都将为false。)

如果不是对象,我的价值就是什么。


1
甚至 $value -is [__ComObject]
Dave_J 2015年


0

如果您像我一样,并且在这里着陆,试图找到一种方法来判断您的PowerShell变量是否是这种不存在的特殊形式:

与它的基础RCW分开的COM对象不能使用。

然后这是一些对我有用的代码:

function Count-RCW([__ComObject]$ComObj){
   try{$iuk = [System.Runtime.InteropServices.Marshal]::GetIUnknownForObject($ComObj)}
   catch{return 0}
   return [System.Runtime.InteropServices.Marshal]::Release($iuk)-1
}

用法示例:

if((Count-RCW $ExcelApp) -gt 0){[System.Runtime.InteropServices.Marshal]::FinalReleaseComObject($ExcelApp)}

从其他人的更好答案中混在一起:

和其他一些有趣的事情:

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.