¿La mejor manera de verificar si existe un objeto PowerShell?


90

Estoy buscando la mejor manera de verificar si existe un objeto Com.

Aquí está el código que tengo; Me gustaría mejorar la última línea:

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

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

Respuestas:


114

Me gustaría seguir con el $nullcheque, ya que cualquier valor distinto ''(cadena vacía), 0, $falsey $nullse pasa a la verificación: if ($ie) {...}.


1
Para usar if ($ val) {...} es mejor para booleanos Todas las demás comprobaciones deben ser if ($ val -ne $ null) {..} Probado yo mismo. TY @Keith Hill
— Ilya Gurenko

65

Tu tambien puedes hacer

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

4
Me gusta esta opción y su negaciónif (-not $ie) { # Do something if $ie doesn't exist/is falsey }
— Chris Magnuson

16

En su ejemplo particular, tal vez no tenga que realizar ninguna verificación . ¿Es posible que New-Objectdevuelva nulo? Nunca he visto eso. El comando debería fallar en caso de un problema y el resto del código en el ejemplo no se ejecutará. Entonces, ¿por qué deberíamos hacer esas comprobaciones?

Solo en el código como a continuación necesitamos algunas verificaciones (la comparación explícita con $ null es la mejor):

# 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
Si el tipo de objeto COM no existe, New-Object lanzará una excepción. Pero no veo cómo podría devolver un valor nulo. Además, ignorar la excepción solo para luego probar nulo es una mala forma.
— JasonMArcher

@JasonMArcher: Estoy de acuerdo con el último comentario, absolutamente. Pero realmente, ¿qué esperarías que escribiera en el ejemplo de demostración? Además, dependiendo de un escenario, incluso este código podría estar bien.
— Roman Kuzmin

Esencialmente, ponga todo el código que usa $ ie dentro del try {}. De esa forma, se salta si hay una excepción.
— JasonMArcher

2
Entonces no sería el código que muestra un caso cuando necesitemos verificar $ null.
— Roman Kuzmin

10

Lo que no destacan todas estas respuestas es que al comparar un valor con $ null, debe poner $ null en el lado izquierdo; de lo contrario, puede tener problemas al comparar con un valor de tipo colección. Ver: 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"
}

El bloque anterior se ejecuta (desafortunadamente). Lo que es aún más interesante es que en Powershell un $ value puede ser $ null y no $ null:

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

Por eso es importante poner $ null en el lado izquierdo para que estas comparaciones funcionen con colecciones:

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

¡Supongo que esto muestra una vez más el poder de Powershell!


Sorprendido, esta respuesta no está más votada, ya que contiene el detalle crítico de poner $nullen el lado izquierdo
— sonyisda1

1

La verificación de tipo con el operador -is devuelve falso para cualquier valor nulo. En la mayoría de los casos, si no en todos, $ value -is [System.Object] será verdadero para cualquier posible valor no nulo. (En todos los casos, será falso para cualquier valor nulo).

Mi valor no es más que un objeto.


1
O incluso $value -is [__ComObject]
— Dave_J


0

En caso de que sea como yo y aterrizó aquí tratando de encontrar una manera de saber si su variable de PowerShell es este sabor particular de inexistente:

No se puede utilizar el objeto COM que se ha separado de su RCW subyacente.

Entonces aquí hay un código que funcionó para mí:

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

ejemplo de uso:

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

mezclados con las mejores respuestas de otras personas:

y algunas otras cosas interesantes que debes saber:

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.