Il modo migliore per verificare se esiste un oggetto PowerShell?


90

Sto cercando il modo migliore per verificare se esiste un oggetto Com.

Ecco il codice che ho; Vorrei migliorare l'ultima riga:

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

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

Risposte:


114

Voglio rimanere con il $nullcontrollo poiché qualsiasi valore diverso ''(stringa vuota) 0, $falsee $nullpasserà il controllo: if ($ie) {...}.


1
Per usare if ($ val) {...} è meglio per i booleani Tutti gli altri controlli dovrebbero essere if ($ val -ne $ null) {..} Testato da solo. TY @ Keith Hill
Ilya Gurenko

65

Puoi anche farlo

if ($ie) {
    # Do Something if $ie is not null
}

4
Mi piace questa opzione e la sua negazioneif (-not $ie) { # Do something if $ie doesn't exist/is falsey }
Chris Magnuson,

16

Nel tuo esempio particolare forse non devi eseguire alcun controllo . È possibile quelloNew-Object restituisca null? Non l'ho mai visto. Il comando dovrebbe fallire in caso di problemi e il resto del codice nell'esempio non verrà eseguito. Allora perché dovremmo fare quei controlli?

Solo nel codice come sotto abbiamo bisogno di alcuni controlli (il confronto esplicito con $ null è il migliore):

# 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
Se il tipo di oggetto COM non esiste, New-Object genererà un'eccezione. Ma non vedo come potrebbe restituire un valore nullo. Inoltre, ignorare l'eccezione solo per verificare la presenza di null è una cattiva forma.
JasonMArcher

@ JasonMArcher: sono assolutamente d'accordo con l'ultima osservazione. Ma davvero, cosa ti aspetti che scriva nell'esempio demo? Inoltre, a seconda dello scenario, anche questo codice potrebbe andare bene.
Roman Kuzmin

In sostanza, metti tutto il codice che usa $ ie all'interno del try {}. In questo modo viene saltato se c'è un'eccezione.
JasonMArcher

2
Quindi non sarebbe il codice che mostra un caso in cui dobbiamo controllare $ null.
Roman Kuzmin

10

Ciò che tutte queste risposte non evidenziano è che quando si confronta un valore con $ null, è necessario inserire $ null sul lato sinistro, altrimenti si potrebbero avere problemi durante il confronto con un valore di tipo raccolta. Vedi: 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"
}

Il blocco sopra è (sfortunatamente) eseguito. La cosa ancora più interessante è che in Powershell un valore $ può essere sia $ null che non $ null:

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

Quindi è importante mettere $ null sul lato sinistro per far funzionare questi confronti con le raccolte:

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

Immagino che questo mostri ancora una volta la potenza di Powershell!


Sorpreso questa risposta non è più votata in quanto contiene il dettaglio critico di mettere $nullsul lato sinistro
sonyisda1

1

Il controllo del tipo con l'operatore -is restituisce false per qualsiasi valore null. Nella maggior parte dei casi, se non tutti, $ value -is [System.Object] sarà vero per ogni possibile valore non nullo. (In tutti i casi, sarà falso per qualsiasi valore nullo.)

Il mio valore non è altro se non un oggetto.


1
O anche $value -is [__ComObject]
Dave_J


0

Nel caso in cui tu sia come me e sei atterrato qui cercando di trovare un modo per capire se la tua variabile di PowerShell è questo particolare sapore di inesistente:

L'oggetto COM che è stato separato dal relativo RCW sottostante non può essere utilizzato.

Quindi ecco un codice che ha funzionato per me:

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

utilizzo di esempio:

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

mischiati insieme dalle risposte migliori di altre persone:

e altre cose interessanti da sapere:

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.