Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Contribuez Discussion :

WD : classe cConsole -> win32 Console


Sujet :

Contribuez

  1. #1
    Expert confirmé
    WD : classe cConsole -> win32 Console
    Cette classe est basée sur la classe WD7DOS (disponible chez sourceforge.net ici) créée par drcharly93 et romu, reprise par Nicolas Compain ici (32 bits 64 bits). Elle permet d'exécuter des commandes win32 console (et non pas DOS comme on a toujours tendance à le dire) sans qu'une fenêtre s'ouvre pour l'utilisateur et avec possibilité d'exploiter le texte renvoyé par la commande. Pour qu'un maximim de personnes puisse l'utiliser, j'ai écrit cette classe sous windev 9. Par rapport à la classe WD7DOS elle apporte les modifications suivantes :
    Définition de procédures de réception et de fin de commande -> ProcReception ProcFinCmd
    Gestion de la conversion de texte OEM vers ANSI (pour les problèmes d'accents en particulier) -> SortieAnsi
    Une procédure de lecture de l'état de la commande -> LireEtat
    Procédure expérimentale de commande asynchrone (ne fonctionne pas pour l'instant) -> ExécuterCommandeAsync

    voici un exemple d'utilisation :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    MaConsole est un cConsole
    MaConsole:SetCommande("ping  192.9.0.5")
    MaConsole<img src="images/smilies/icon_razz.gif" border="0" alt="" title=":P" class="inlineimg" />rocReception = "MaProcReception"
    MaConsole<img src="images/smilies/icon_razz.gif" border="0" alt="" title=":P" class="inlineimg" />rocFinCmd = "MaProcFin"
    MaConsole:ExécuterCommande()
    SI ChaîneOccurrence(MaConsole:SortieAnsi(),"dépassé") ALORS 
    Erreur("TimeOut Ping")
    SINON
    	 Info(MaConsole:SortieAnsi())
    FIN


    Avec par exemple pour les procédures locales MaProcReception et MaProcFin :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
     
    PROCEDURE MaProcReception(pSortie est une chaîne)
    Trace(OemToAnsi(pSortie))



    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
     
    PROCEDURE MaProcFin()
    Trace("Commande win32 console  terminée")


    Si vous avez une version de windev qui exploite les entiers système ( pour version 32 64 bits) il faut enlever les commentaires dans entier //système (windev 9 ne gérait pas les entiers système).


    Si vous avez des remarques à faire, des améliorations ou des corrections à apporter, des bugs à signaler faites le en forum et pas dans la contribution pour ne pas la "polluer" .

    Ceci est la version bêta 0.1 de la classe cConsole. Elle est fournie comme cela (as is). L'utilisation de cette classe est à vos risques et périls et je ne saurais être responsable des problèmes ou des préjudices rencontrés.

    Ami calmant, J.P
    Jurassic computer : Sinclair ZX81 - Zilog Z80A à 3,25 MHz - RAM 1 Ko - ROM 8 Ko

  2. #2
    Expert confirmé
    version 1.0
    voici une nouvelle mouture de la classe
    changements :
    // version 1.0 Jurassic.Pork - 9 juillet 2012
    la version est compatible 32 bits 64 bits.
    les noms des méthodes ont changé (plus courtes).
    Modification de la méthode ExécuterCmdAsync utilisation d'un ExécuterCmd lancé dans un threadExécute.
    Ajout du numéro de version en constante (cConsole::Version).
    Correction de la méthode d'arrêt.
    Les procédures ExécuterCmdAsync et ExécuterCmd renvoient maintenant le code Retour de la commande ou un code d'erreur interne.
    Amélioration des performances de lecture du pipe en utilisant un buffer de 4096 octets (au lieu de 256).

    la version minimum sera windev 12 car en windev 9 j'avais un problème avec le threadexécute sur une méthode de classe. En plus comme cela la version est compatible 32 bits 64 bits.
    J'ai mis un projet exemple dans le dépôt PCSOFT ici

    Ami calmant, J.P
    Jurassic computer : Sinclair ZX81 - Zilog Z80A à 3,25 MHz - RAM 1 Ko - ROM 8 Ko

  3. #3
    Membre confirmé
    Super mec, c'est exactement ce que je voulais

  4. #4
    Membre chevronné
    Salut JP,

    je ne sais pas si je fais bien de remonter ce post mais je voulais remonter une anomalie dans la classe....

    En fait j'ai constaté que le test sur le retour de "CreateProcessA" n'est pas cohérent avec la documentation MSDN.
    Dans la doc il indique le retour est égal à 0 s'il y a un pb lors de l'exécution de la commande or le test effectué est <> 1.

    Dans mon contexte (je teste la présence et la version de Java) cela posait un problème dans le cas où l'on venait d'installer le programme que l'on cherche à lancer.

    J'ai donc modifié la procédure ExécuterCmd :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    SI API("kernel32","CreateProcessA",lpApplicationName,&:mCommande,&Sa,&Sa,bInheritHandles,::NORMAL_PRIORITY_CLASS,lpEnvironment,lpCurrentDirectory,&Start,&<img src="images/smilies/icon_razz.gif" border="0" alt="" title=":P" class="inlineimg" />rocI) = 0 ALORS
    	//	Si une erreur, fermeture des Handles
    	Resultat = API("KERNEL32","CloseHandle",:HdLecturePipe)
    	Resultat = API("KERNEL32","CloseHandle",:HdEcriturePipe)
    	//Erreur("Fichier ou commande non trouvé.")
    	:EnCours = Faux
    	RENVOYER -1
    FIN


    Voilà, c'est tout....
    SQL : le véritable Esperanto

    "Les patates à ta tata épatent ton tonton mais les pates aux thons à ton tonton épatent pas ta tata." (Michel Souris)

    MERCI DE NE PAS M'ENVOYER DE MESSAGE PRIVE POUR DES QUESTIONS TECHNIQUES SANS MON ACCORD !

  5. #5
    Expert confirmé
    Hello,
    merci Michel de ta remarque fort justifiée , j'ai mis à jour la classe (en pièce jointe) :

    // ===================================================
    // Version 1.1 Août 2015
    // Suite à remarque de Michel Souris
    // Correction du test du retour des CreateProcessA (Méthodes ExécuterCmd)
    code modifié :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    SI API("kernel32","CreateProcessA",lpApplicationName,&:mCommande,&Sa,&Sa,bInheritHandles,::NORMAL_PRIORITY_CLASS,lpEnvironment,lpCurrentDirectory,&Start,&<img src="images/smilies/icon_razz.gif" border="0" alt="" title=":P" class="inlineimg" />rocI) = 0 ALORS
    	//	Si une erreur, fermeture des Handles
    	Resultat = API("KERNEL32","CloseHandle",:HdLecturePipe)
    	Resultat = API("KERNEL32","CloseHandle",:HdEcriturePipe)
    	Erreur("Erreur dans CreateProcessA. Possibilité : Fichier ou commande non trouvé. ")
    	:EnCours = Faux
    	RENVOYER -1
    FIN


    Ami calmant, J.P
    Jurassic computer : Sinclair ZX81 - Zilog Z80A à 3,25 MHz - RAM 1 Ko - ROM 8 Ko

  6. #6
    Nouveau membre du Club
    Interaction IHM dans un thread
    Bonjour à toutes et tous,

    Petit message à Jurassic Pork.
    Je découvre la classe et elle fait exactement ce dont j'ai besoin ... Grand merci !!!

    Néanmoins, je remarque que tu utilises un thread secondaire dans la méthode ExécuterCmdAsync() et que celui-ci appelle la méthode ExécuterCmd().
    S'agissant d'une exécution dans un thread secondaire il ne doit y avoir AUCUNE interaction avec l'IHM. Or dans ExécuterCmd() tu as placé des messages Erreur() qui sont autant de risques de plantages.

    J'opte personnellement dans ce cas pour des traces dans un fichier journal (log).

    Et encore merci pour ce boulot qui me dépanne bien.

###raw>template_hook.ano_emploi###