PC SOFT

FORUMS PROFESSIONNELS
WINDEVWEBDEV et WINDEV Mobile

Accueil → WINDEV 2024 → Question WMI
Question WMI
Débuté par Serge LANTHIER, 06 juil. 2020 06:43 - 4 réponses
Membre enregistré
213 messages
Popularité : +12 (12 votes)
Posté le 06 juillet 2020 - 06:43
Bonjour,

Je suis à me créer un ensemble de services WMI.
- Depuis l'idée de Philippe Pasquali et son ggWMI.
- Depuis l'idée de cConsole de Jurrasic Pork.

J'ai fait de bons progrès mais tout naturellement, je bloque.

Une table de test avec avec Win32_BIOS.





Déclarations globales (Tableaux avec agrandissement...)
ciWMITyp est un tableau <agrandissement = 1> de chaînes // Chaîne, entier, etc.
ciWMIClé est un tableau <agrandissement = 1> de chaînes // Clé pour appel WMI
ciWMIVal est un tableau <agrandissement = 1> de chaînes // Valeurs retournées



Routine appelée par le bouton de test:
Procedure ciPosteWMIWin32Bios(pPoste est une chaîne = NetNomMachine())
//
gWMIClasse = "Win32_BIOS"
//
Ajoute(ciWMITyp, "uint16") ; Ajoute(ciWMIClé, "BiosCharacteristics[]")
Ajoute(ciWMITyp, "string") ; Ajoute(ciWMIClé, "BIOSVersion[]")
Ajoute(ciWMITyp, "string") ; Ajoute(ciWMIClé, "BuildNumber")
Ajoute(ciWMITyp, "string") ; Ajoute(ciWMIClé, "Caption")
Ajoute(ciWMITyp, "string") ; Ajoute(ciWMIClé, "CodeSet")
... et les autres...
//
ciWMIAppel(pPoste, gWMIClasse)
//
//--- EOF



Routine pour l'appel à WMI
Procedure PRIVÉ ciWMIAppel(pPoste est une chaîne, pClasse est une chaîne = "")
//
Validations...
//
x est un entier = 1
TANTQUE x <= lNombreClés ET lValidation = Vrai
//--- Retire les [] non utiles pour l'appel
SI Droite(ciWMIClé[x], 2) = "[]" ALORS ciWMIClé[x] = Gauche(ciWMIClé[x], Taille(ciWMIClé[x]) - 2)
SI SansEspace(ciWMIClé[x]) <> "" ALORS
//--- clé présente, on extrait
ciWMIVal[x] = ciWMIExtrait(pPoste, pClasse, ciWMIClé[x])
SINON
//--- Clé à vide, on passe
ciWMIVal[x] = ""
FIN
x ++
FIN



Routine d'extraction elle-même.
Procedure PRIVÉ ciWMIExtrait(pPoste est une chaîne, pClasse est une chaîne = "", pCle est une chaîne = "")
QUAND EXCEPTIONEXCEPTION DANS
gObjService = gObjLocator >> ConnectServer(".","root\cimv2")
gObjService >> Security_ >> ImpersonationLevel = 3
//
gObjValNum = 0
gObjExtract = gObjService >> ExecQuery("SELECT " + pCle + " FROM " + pClasse)
//
SI gObjExtract >> Count ALORS
gObjValTxt = gObjExtract >> ItemIndex(0) >> Properties_ >> Item(pCle) >> Value
FIN
RENVOYER gObjValTxt
FAIRE
RENVOYER "Non reconnu..."
FIN



Je passe la classe (Win32_BIOS) et la clé (Ex: Caption).

En bouclant, je m'assure d'un résultat même s'il y a une exception sur l'un des items.
Fonctionne parfaitement sauf pour les trois clés qui sont des tableaux de valeurs.
BiosCharacteristics, BIOSVersion et ListOfLanguages.

Je passe les trois sans les [ et ].

Il y a quelque chose qui m'échappe avec SI gObjExtract >> Count
J'ai bien tenté de faire une boucle x et ItemIndex(x), mais il refuse...

Comment puis-je traiter les "tableaux" de valeurs tels BiosCharacteristics ?


Exemple de Microsoft:
Win32_Bios WMI Information
Bios Characteristics
                      :  04-ISA is supported
                      :  07-PCI is supported
                      :  08-PC Card (PCMCIA) is supported
                      :  09-Plug and Play is supported
Bios Version          :  DELL   - 27d60a0d
Codeset               :
CurrentLanguage       :  en|US|iso8859-1
Description           :  Phoenix ROM BIOS PLUS Version 1.10 A04
IdentificatonCode     :



D'avance, merci pour votre aide.

Serge

--
-----
Parfois, la logique est implacable...
Membre enregistré
962 messages
Popularité : +183 (185 votes)
Posté le 06 juillet 2020 - 13:15
hello,
va faire peut-être un tour ici :
https://forum.pcsoft.fr/fr-FR/pcsoft.fr.windev/54665-api-winspool-drv-statut-imprimante-197829/read.awp

pour voir comment récupérer un tableau renvoyé par WMI.

--
Ami calmant, J.P
Membre enregistré
213 messages
Popularité : +12 (12 votes)
Posté le 06 juillet 2020 - 15:27
Salut,



Exactement le bout de code que je cherchais, mais je dois conserver le ItemIndex(0).
gObjValTxt = ciWMITableau(gObjExtract >> ItemIndex(0) >> Properties_ >> Item(pCle) >> Value
:merci:

Maintenant que c'est fonctionnel... une seconde question...

Dans cet exemple, Win32_BIOS compte 31 clés et donc je fais autant d'appel à ma routine d'extraction.
gObjService >> ExecQuery("SELECT " + pCle + " FROM " + pClasse

Efficace, Windev, c'est instantané, mais j'aurais préféré un seul appel

Je peux adapter mon code sans difficulté.
gObjService >> ExecQuery("SELECT * FROM " + pClasse
Boucle pour extraire la valeur de chaque clé.
gObjValTxt = ciWMITableau(gObjExtract >> ItemIndex(0) >> Properties_ >> Item(pCle) >> Value
FIN

Mais s'il y a une exception, disons à la troisième clé de ma boucle, je sors...
Avec Microsoft qui peut changer les clés je dois prévoir l'exception...

QUAND EXCEPTION DANS
Est-il possible de tester pour la validité de la clé avant de tenter d'en récupérer la valeur ?
FAIRE
Question d'éviter de provoquer une exception...
FIN

Merci.

Serge

--
-----
Parfois, la logique est implacable...
Membre enregistré
962 messages
Popularité : +183 (185 votes)
Posté le 10 juillet 2020 - 08:24
hello,
avec l'assemblage dotnet System.Management, on peut sous Windev, récupérer toutes les propriétés de la classe Win32_Bios sans les connaître. Voici un exemple de code qui fait cela :
osClass est un ManagementClass("Win32_Bios")
objManagement est un ManagementObject dynamique
props est un PropertyDataCollection dynamique
prop est une PropertyData dynamique
monTableau est un tableau de Variants
maValeur est un Variant
valeurProp est une chaîne
x est un entier
osClass.Options.UseAmendedQualifiers = Vrai
props = osClass.Properties
POUR TOUT prop de props
POUR TOUT objManagement de osClass.GetInstances()
valeurProp = ""
SI prop.isarray ALORS
monTableau = objManagement.Properties.get_Item(prop.Name).Value
POUR x = 1 _A_ TableauOccurrence(monTableau)
SI monTableau[x] = Null ALORS valeurProp += "<NULL>" + ","
SI VariantConvertit(monTableau[x],wlChaîne) ALORS valeurProp += monTableau[x] + ","
FIN
SINON
maValeur = objManagement.Properties.get_Item(prop.Name).Value
SI maValeur = Null ALORS valeurProp = "<NULL>"
SI VariantConvertit(maValeur,wlChaîne) ALORS valeurProp = maValeur
FIN
FIN
Trace("Property Name: ", prop.Name, " -> " ,valeurProp)
// Trace("Property type: ", prop.Type.ToString())
FIN


voici le résultat :




Je ne sais pas si cela marchera pour toutes les classes WMI.

--
Ami calmant, J.P
Membre enregistré
213 messages
Popularité : +12 (12 votes)
Posté le 11 juillet 2020 - 15:41
Salut,

J'avais résolu mon problème en encapsulant le QUAND EXCEPTION dans une seconde procédure.
Avec un contrôle approprié, la première procédure relance la seconde sur exception.

Fonctionne à merveille avec toutes les classes du Computer System Hardware.
Je n'ai pas encore testé avec les autres classes des autres Providers de WMI.

---
Ceci étant, je ne suis pas encore parvenu à émuler le code que tu proposes en m'en tenant à WMI.

Je peux avoir le décompte des objets (Ex: deux imprimantes)
gObjExtract >> Count

Je peux avoir le compte des propriétés (Ex: 31 propriétés)
gObjExtract >> ItemIndex(gSeqObj) >> Properties_ >> Count

Mais je ne peux "lister" les propriétés par leurs noms même si je sais combien il y en a...
gObjExtract >> ItemIndex(gSeqObj) >> Properties_ >> Item(gSeqPropriété) >> Name <--- Provoque une exception

Item() persiste et signe, il veut que je lui donne le "nom" de la propriété...
Impossible de lui passer le numéro pour en extraire le nom...

Je vais finir par trouver.
;)

Merci pour la réponse.

Serge

--
-----
Parfois, la logique est implacable...