Question [Astuce] Copier une collection dans un tableau
- Laurent Dardenne
- Auteur du sujet
- Hors Ligne
- Modérateur
- Messages : 6302
- Remerciements reçus 68
[code:1]
#Récupère le premier disque
$Disque=gwmi Win32_DiskDrive|select -first 1
#Récupère les associations (WMI) du disque
$TempAssociations=$Disque.psbase.GetRelationships()
$TempAssociations[0]
#exception
#Impossible d'indexer dans un objet de type System.Management.ManagementObjectCollection.
[/code:1]
Cette erreur est dû au fait que la classe ManagementObjectCollection n'implémente pas l'interface IList qui elle gére les accès indexés dans une collection:
[code:1]
$TempAssociations.GetType().GetInterfaces()
# IsPublic IsSerial Name BaseType
#
----
# True False ICollection
# True False IEnumerable
# True False IDisposable
[/code:1]
On peut convertir la collection dans un tableau à l'aide de la méthode CopyTo() de l'interface ICollection :
[code:1]
if ($TempAssociations -is [System.Collections.ICollection])
{
#crée un tableau de la taille de la collection
$Associations=new-object Object[] $TempAssociations.count
#On recopie la collection dans le tableau à partir de l'index 0
$TempAssociations.CopyTo($Associations,0)
}
else {Write-Warning \"L'objet n'implémente pas l'interface ICollection\"}
#On supprime la collection inutile
$TempAssociations.Dispose()
$TempAssociations=$Null
$Associations[0]
[/code:1]
Tutoriels PowerShell
Connexion ou Créer un compte pour participer à la conversation.
- Laurent Dardenne
- Auteur du sujet
- Hors Ligne
- Modérateur
- Messages : 6302
- Remerciements reçus 68
Tutoriels PowerShell
Connexion ou Créer un compte pour participer à la conversation.
- Matthew BETTON
- Hors Ligne
- Membre platinium
- Messages : 968
- Remerciements reçus 0
Laurent Dardenne écrit:
Pour info, le comportement est différent avec la Version 3 de Powershell, le code ne génère plus d'exception.
Le code ne génère plus d'erreur... il ne renvoie pas non plus le premier élément mais toute la collection
Merci Laurent
@ +
Matthew
Connexion ou Créer un compte pour participer à la conversation.
- Laurent Dardenne
- Auteur du sujet
- Hors Ligne
- Modérateur
- Messages : 6302
- Remerciements reçus 68
C'est vrai, je n'avais pas remarqué, mais étant dans un comportment liè à une interface, je ne suis pas plus surpris que ça, mais tu fais bien de le préciser.il ne renvoie pas non plus le premier élément mais toute la collection
Ensuite d'expliquer ça, je te laisse la main
C'est pas évident, voir accessoire.
Sinon on peut demander aux formateurs PowerShell. Alors donc, une idée ?
Tutoriels PowerShell
Connexion ou Créer un compte pour participer à la conversation.
- Matthew BETTON
- Hors Ligne
- Membre platinium
- Messages : 968
- Remerciements reçus 0
Matthew BETTON écrit:
Ensuite d'expliquer ça, je te laisse la mainil ne renvoie pas non plus le premier élément mais toute la collection
Et bien.. Je ne vois pas, d'autant plus que la propriété 'count' renvoie bien le nombre d'éléments :
[code:1]$TempAssociations.count
#6 (dans mon cas, bien entendu)[/code:1]
Alors là, je deviens bigleux... Je suis dans le \"cloud\" !
Ce comportement reste une énigme (pour moi ?).
Connexion ou Créer un compte pour participer à la conversation.
- Laurent Dardenne
- Auteur du sujet
- Hors Ligne
- Modérateur
- Messages : 6302
- Remerciements reçus 68
Matthew BETTON écrit:
Avec PS v2 :il ne renvoie pas non plus le premier élément mais toute la collection
[code:1]
(1)[0]
[ : Impossible d'indexer dans un objet de type System.Int32.
[/code:1]
On obtient une exception, si on indexe une type qui ne peut l'être.
Avec PS v3 :
[code:1]
(1)[0]
1
[/code:1]
On obtient la valeur, sans déclenchement d'exception.
Donc, le premier post de ce thread ( $TempAssociations[0] ) est tjr cohérent avec la V2.
Ce qu'on peut constater est que ce n'est pas parce que le parseur accepte une syntaxe indexée ( la présence de [] ) sur une collection que celle-ci peut l'être.
PS v3 ajoute un couche ( de confusion ?) en donnant l'impression qu'on peut tout indexer, bien qu'il reste une logique ($null[0] n'est pas autorisé).
Pour tester le comportement d'indexation sur une collection voir ce post .
L'appel de
[code:1]
Test-AccessedByIndex $TempAssociations
[/code:1]
sur les deux versions renvoit False. Donc là, si on adresse le comportement, porté par l'interface IList, on est assuré du résultat, cette variable ne peut être indexée.
Ici on n'adresse pas le parseur PS , mais le framework dotNET, bye bye les farceurs...
Matthew BETTON écrit:
Oui, tu as raison, remarque que tu utilises le terme de 'propriété', l'information existe. L'indexation est un comportement, une possibilité de manipulation.d'autant plus que la propriété 'count' renvoie bien le nombre d'éléments
Une propriété existe ou pas.
En dotNET, une collection de données peut implémenter un ou plusieurs comportements, toute collection est au moins un ensemble de données (on laisse de côtè les ensembles vide).
Un ensemble de données peut ne pas être ordonnées, exemple les hashtables ( @{} ), voir ne pas être 'itérable à volonté' (pas sûr du terme).
Exemple issu de mon tutoriel Powershell sur le pipeline :
[code:1]
Function MaFonction
{
Write-host \"`tDonnées dans la fonction2-1 : $input\" -F Yellow
Write-host \"`tEt l'écho répond : Données dans la fonction2-1 : $input\" -F Green
}
1..3|MaFonction
[/code:1]
Ici $Input est une collection, mais sa première itération place un curseur interne sur la fin de la collection.
Le fait d'adresser à nouveau cette collection, ne renvoie rien, normal une fois le 'curseur' en fin, on ne peut aller au delà.
Essayons autre chose :
[code:1]
Function MaFonction
{
Write-host \"`tDonnées dans la fonction2-1 : $input\" -F Yellow
$Input.Reset()
Write-host \"`tEt l'écho répond : Données dans la fonction2-1 : $input\" -F Green
}
1..3|MaFonction
[/code:1]
Ici le fait de replacer le curseur au 'début', permet de corriger le pb d'affichage.
Je te laisse digérer ça, en espérant t'avoir apporté qq lumières.<br><br>Message édité par: Laurent Dardenne, à: 12/12/12 17:36
Tutoriels PowerShell
Connexion ou Créer un compte pour participer à la conversation.
- Vous êtes ici :
- Accueil
- forum
- PowerShell
- Contributions à la communauté
- [Astuce] Copier une collection dans un tableau