21 novembre 2013
publié par 
Ce billet rejoint un thème déjà abordé dans le blog, et revenant régulièrement à notre support : pourquoi la même application peut donner le résultat attendu sur 20 postes, mais sur le 21ième une différence apparaît (effet d'affichage, formatage de donnée, communication avec un périphérique, échange avec une base tierce, un webservice ...).

Dans ce cas bien sûr il faut orienter les recherches sur la configuration elle-même, et non pas sur l'application. Il ne faudrait pas inverser la tendance en modifiant l'application à la hâte, et se retrouver avec le bon résultat sur 1 poste, et non pas sur les 20...

Pour le cas des accès aux bases de données, c'est majoritairement une erreur sur la version du client de la base de données qui peut provoquer des différences (cf. Accès aux bases de données Client/Serveur, attention à la version du client). Et dans la quasi totalité des cas, une différence dans les dépendances de l'application sera à l'origine des complications.

Voici donc un bout de code que je conseille vivement de placer dans les applications, suivant le cas avec une option "avancée", ou une option d'administration, ou un raccourci caché. Il permet d'obtenir une liste complètes avec emplacements et versions des :
  • DLL du framework WINDEV,
  • DLL de Windows qui sont instanciées par l'application,
  • DLL des éventuels clients des bases de données utilisées,
  • composants externes.
Par comparaison entre un poste sain et une configuration récalcitrante, il devient ainsi immédiatement possible de repérer les différences : un client base de données trop ancien, un composant qui n'a pas été mis à jour, un framework chargé qui n'est pas celui pour lequel l'application est prévue...

strFramework est une structure
sExtension est une chaîne
sModule est une chaîne
sRépertoire est une chaîne
sVersion est une chaîne
sVI est une chaîne
sInfo est une Buffer
FIN

TabDépendance est un tableau de strFramework
UnElement est un strFramework

sListeProcessus est une chaîne
nPID est un entier
sAppli est une chaîne

sDLLInfo est une chaîne
sDLLListe est une chaîne
sNomDLL est une chaîne
sInfoElement est une chaîne = [
Copyright : %1
Description : %2
Mode : %3
Société : %4
VI : %5
Commentaires : %6
]

// Recherche du PID du programme en cours ...
sListeProcessus = ExeListeProcessus(exePID, exeNomCourt)
POUR TOUTE chaîne sProcessus de SEPAREE PARssus SEPAREE PAR RC
nPID = ExtraitChaîne(sProcessus, 1, TAB)
sAppli = ExtraitChaîne(sProcessus, 2, TAB)
SI sAppli ~= (EnModeTest() ? "WDTST.EXE" SINON ProjetInfo(piNomEXE)) ALORS SORTIR
FIN

// Récupération des DLL pour le PID trouvé ...
sDLLListe = ExeListeDLL(nPID)
POUR TOUTE chaîne sDLL de SEPAREE PAREPAREE PAR RC

sNomDLL = Majuscule(fExtraitChemin(sDLL, fFichier+fExtension))

sDLLInfo += [RC] + sNomDLL + " " + ExeInfo(exeVersion, sDLL)
UnElement.sExtension = fExtraitChemin(sDLL, fExtension)
UnElement.sModule = sNomDLL
UnElement.sVersion = ExeInfo(exeVersion, sDLL)
UnElement.sVI = ExeInfo("VersionVI", sDLL)
UnElement.sRépertoire = fExtraitChemin(sDLL, fDisque+fRépertoire)
UnElement.sInfo = ChaîneConstruit(sInfoElement, ExeInfo(exeCopyright, sDLL), ExeInfo(exeDescription, sDLL),
ExeInfo(exeMode, sDLL), ExeInfo(exeSociété, sDLL),
ExeInfo("VersionVI", sDLL), ExeInfo("Commentaires", sDLL))

TableauAjoute(TabDépendance, UnElement)

FIN

// Récupération de la liste des composants utilisés par l'application...
sComposantNom, sComposantChemin, sComposantRépertoire sont des chaînes
POUR TOUTE chaîne sUnComposant de ComposantListe(SEPAREE PARAR RC
sComposantNom = ExtraitChaîne(sUnComposant, 1, TAB)
sComposantChemin = ExtraitChaîne(sUnComposant, 2, TAB)
sComposantRépertoire = fExtraitChemin(sComposantChemin, fDisque+fRépertoire)
UnElement.sModule = sComposantNom
UnElement.sRépertoire = sComposantRépertoire
UnElement.sVersion = ComposantInfo(sComposantNom, ciVersion, sComposantRépertoire)
UnElement.sVI = ComposantInfo(sComposantNom, ciVersionInterne, sComposantRépertoire)
UnElement.sInfo = ChaîneConstruit("Société émettrice : %1", ...
ComposantInfo(sComposantNom, ciSociété, sComposantRépertoire),
ComposantInfo(sComposantNom, ciCopyright, sComposantRépertoire),
ComposantInfo(sComposantNom, ciLibellé, sComposantRépertoire),
ComposantInfo(sComposantNom, ciVersion, sComposantRépertoire),
ComposantInfo(sComposantNom, ciVersionCompatible, sComposantRépertoire),
ComposantInfo(sComposantNom, ciVersionInterne, sComposantRépertoire),
ComposantInfo(sComposantNom, ciVersionProjet, sComposantRépertoire),
ComposantInfo(sComposantNom, ciNuméroPatch, sComposantRépertoire),
ComposantInfo(sComposantNom, ciNomPhysique, sComposantRépertoire),"")
TableauAjoute(TabDépendance, UnElement)
FIN


// Visualisation du tableau dans une trace pour l'exemple
// le plus simple est de déclarer en global le tableau TabDépendance
// afin de le visualiser directement dans un champ table par databinding
POUR TOUT ELEMENT UnElement de TabDépendance
Trace(UnElement.sModule+"//"+UnElement.sVersion)
FIN



Le code est autonome et peut être directement copié/collé dans un bouton par exemple.

< Retour

Publier un commentaire : 
Votre adresse email ne sera pas publiée


© 2019 PC SOFT. Tous droits réservés. Réalisé  avec WEBDEV