Der beste Weg, um zu überprüfen, ob ein PowerShell-Objekt vorhanden ist?

89

Ich suche nach dem besten Weg, um zu überprüfen, ob ein Com-Objekt vorhanden ist.

Hier ist der Code, den ich habe; Ich möchte die letzte Zeile verbessern:

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

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

Antworten:

113

Ich würde bei der $nullPrüfung bleiben , da jeder andere Wert als ''(leere Zeichenfolge) 0, $falseund $nulldie Prüfung bestehen : if ($ie) {...}.

Keith Hill
quelle
1
Zu verwenden, wenn ($ val) {...} für Boolesche Werte besser ist Alle anderen Überprüfungen sollten if ($ val -ne $ null) {..} sein. TY @Keith Hill
Ilya Gurenko
65

Sie können auch tun

if ($ie) {
    # Do Something if $ie is not null
}
Ravikanth
quelle
4
Ich mag diese Option und ihre Verneinungif (-not $ie) { # Do something if $ie doesn't exist/is falsey }
Chris Magnuson
16

In Ihrem speziellen Beispiel müssen Sie möglicherweise überhaupt keine Überprüfungen durchführen . Ist das möglich, dass New-Objectnull zurückgegeben wird? Das habe ich noch nie gesehen. Der Befehl sollte im Falle eines Problems fehlschlagen und der Rest des Codes im Beispiel wird nicht ausgeführt. Warum sollten wir diese Überprüfungen überhaupt durchführen?

Nur im folgenden Code benötigen wir einige Überprüfungen (expliziter Vergleich mit $ null ist am besten):

# 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) {
    ...
}
Roman Kuzmin
quelle
1
Wenn der COM-Objekttyp nicht vorhanden ist, löst New-Object eine Ausnahme aus. Aber ich sehe nicht, wie es eine Null zurückgeben könnte. Außerdem ist es eine schlechte Form, die Ausnahme nur zu ignorieren, um dann auf Null zu testen.
JasonMArcher
@ JasonMArcher: Ich stimme der letzten Bemerkung absolut zu. Aber wirklich, was würden Sie erwarten, dass ich in das Demo-Beispiel schreibe? Außerdem kann je nach Szenario sogar dieser Code in Ordnung sein.
Roman Kuzmin
Fügen Sie im Wesentlichen den gesamten Code, der $ ie verwendet, in try {} ein. Auf diese Weise wird es übersprungen, wenn es eine Ausnahme gibt.
JasonMArcher
2
Dann wäre es nicht der Code, der einen Fall anzeigt, wenn wir nach $ null suchen müssen.
Roman Kuzmin
10

Was all diese Antworten nicht hervorheben, ist, dass Sie beim Vergleich eines Werts mit $ null $ null auf der linken Seite setzen müssen, da Sie sonst beim Vergleich mit einem Wert vom Typ Sammlung möglicherweise Probleme bekommen. Siehe: 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"
}

Der obige Block wird (leider) ausgeführt. Noch interessanter ist, dass in Powershell ein $ -Wert sowohl $ null als auch nicht $ null sein kann:

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

Daher ist es wichtig, $ null auf der linken Seite zu setzen, damit diese Vergleiche mit Sammlungen funktionieren:

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

Ich denke, dies zeigt noch einmal die Kraft von Powershell!

Dag Wieers
quelle
Überrascht ist diese Antwort nicht mehr positiv bewertet, da sie das kritische Detail des Auflegens $nullauf der linken Seite enthält
sonyisda1
1

Die Typprüfung mit dem Operator -is gibt false für jeden Nullwert zurück. In den meisten Fällen, wenn nicht allen, ist $ value -is [System.Object] für jeden möglichen Wert ungleich Null wahr. (In allen Fällen ist es für jeden Nullwert falsch.)

Mein Wert ist nichts, wenn nicht ein Objekt.

Aron
quelle
1
Oder sogar $value -is [__ComObject]
Dave_J
0

Wenn Sie wie ich sind und hier gelandet sind, um herauszufinden, ob Ihre PowerShell-Variable diese bestimmte Variante von nicht vorhanden ist:

COM-Objekt, das von der zugrunde liegenden RCW getrennt wurde, kann nicht verwendet werden.

Dann ist hier ein Code, der für mich funktioniert hat:

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

Anwendungsbeispiel:

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

zusammengesetzt aus den besseren Antworten anderer Leute:

und einige andere coole Dinge zu wissen:

Gregor y
quelle