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.