La meilleure façon de vérifier si un objet PowerShell existe?


90

Je recherche la meilleure façon de vérifier si un objet Com existe.

Voici le code que j'ai; J'aimerais améliorer la dernière ligne:

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

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

Réponses:


114

Je tiendrais avec le $nullchèque depuis une valeur autre que ''(chaîne vide), 0, $falseet $nullpassera le contrôle: if ($ie) {...}.


1
Utiliser if ($ val) {...} est mieux pour les booléens Toutes les autres vérifications devraient être if ($ val -ne $ null) {..} Je me suis testé. TY @Keith Hill
— Ilya Gurenko

65

Vous pouvez aussi faire

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

4
J'aime cette option et sa négationif (-not $ie) { # Do something if $ie doesn't exist/is falsey }
— Chris Magnuson

16

Dans votre exemple particulier, vous n'avez peut-être aucun contrôle à effectuer . Est-ce possible queNew-Object retourne null? Je n'ai jamais vu ça. La commande devrait échouer en cas de problème et le reste du code de l'exemple ne sera pas exécuté. Alors pourquoi devrions-nous faire ces vérifications?

Seulement dans le code comme ci-dessous, nous avons besoin de quelques vérifications (la comparaison explicite avec $ null est la meilleure):

# 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 le type d'objet COM n'existe pas, New-Object lèvera une exception. Mais je ne vois pas comment cela pourrait renvoyer un null. En outre, ignorer l'exception uniquement pour ensuite tester la valeur null est une mauvaise forme.
— JasonMArcher

@JasonMArcher: Je suis d'accord avec la dernière remarque, absolument. Mais vraiment, qu'espérez-vous que j'écrive dans l'exemple de démonstration? En outre, selon un scénario, même ce code pourrait être très bien.
— Roman Kuzmin

Essentiellement, mettez tout le code qui utilise $ ie dans le try {}. De cette façon, il est ignoré s'il y a une exception.
— JasonMArcher

2
Ensuite, ce ne serait pas le code montrant un cas où nous devons vérifier $ null.
— Roman Kuzmin

10

Ce que toutes ces réponses ne mettent pas en évidence, c'est que lorsque vous comparez une valeur à $ null, vous devez mettre $ null sur le côté gauche, sinon vous risquez d'avoir des problèmes lors de la comparaison avec une valeur de type collection. Voir: 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"
}

Le bloc ci-dessus est (malheureusement) exécuté. Ce qui est encore plus intéressant, c'est que dans Powershell, une valeur $ peut être à la fois $ null et non $ null:

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

Il est donc important de mettre $ null sur le côté gauche pour que ces comparaisons fonctionnent avec les collections:

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

Je suppose que cela montre encore une fois la puissance de Powershell!


Surpris, cette réponse n'est pas plus votée car elle contient le détail critique de la mise $nullsur le côté gauche
— sonyisda1

1

La vérification de type avec l'opérateur -is renvoie false pour toute valeur nulle. Dans la plupart des cas, sinon tous, $ value -is [System.Object] sera vrai pour toute valeur non nulle possible. (Dans tous les cas, il sera faux pour toute valeur nulle.)

Ma valeur n'est rien sinon un objet.


1
Ou même $value -is [__ComObject]
— Dave_J


0

Au cas où vous êtes comme moi et vous avez atterri ici en essayant de trouver un moyen de savoir si votre variable PowerShell est cette saveur particulière d'inexistant:

L'objet COM qui a été séparé de son RCW sous-jacent ne peut pas être utilisé.

Ensuite, voici un code qui a fonctionné pour moi:

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

exemple d'utilisation:

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

écrasés à partir des meilleures réponses des autres:

et quelques autres choses intéressantes à savoir:

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.