Rediriger l'invite de commande dans une zone de texte

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
NY152
Messages : 148
Inscription : dim. 14/mai/2006 20:41

Re: Rediriger l'invite de commande dans une zone de texte

Message par NY152 »

En capturant un programme tel que chkdsk, ffmpeg et bien d'autre, dès qu'une ligne UNIQUE d'un programme voit sa composition changer (comme un pourcentage), cette dernière est alors considérée comme une nouvelle ligne lors de la capture alors que ce n'est pas le cas. Aussi nous nous trouvons avec un retour du programme totalement déstructuré et peu lisible. Il doit être possible de "corriger" cela mais je ne sait pas comment. On parlait du programme Take Command en début de post et ce programme (qui schématiquement, envois et récupère les entrées/sorties de programme), lui, ne se retrouve pas avec ce genre pollutions visuelles ^^

EDIT :

Je remet si dessous le post de cage. Son test de chkdsk illustre bien le phénomène de doublon de ligne qui n'ont pas lieu d'être.
cage a écrit :J'ai essayé la commande chkdsk avec la méthode clip et cela fonctionne

Code : Tout sélectionner

ClearClipboard()

program$ = "cmd.exe"

progr$ = "chkdsk.exe"

param$ = "d:"

parameter$ = "/c "+progr$+" "+param$+" 2>&1|clip"

rc = RunProgram(program$,parameter$,#Null$,#PB_Program_Wait)

Debug GetClipboardText()
J'ai coché la case Request Administrator mode for Windows Vista and above
et voici de résultat:
Le type du système de fichiers est NTFS.
Le nom de volume est Recover.

AVERTISSEMENT ! Le paramètre /F n'a pas été spécifié.
Exécution de CHKDSK en mode lecture seule.

Étape 1 : Examen de la structure du système de fichiers de base...
État d'avancement : 0 de 68864 effectué(s) ; Étape : 0% ; Total : 0% ; Heure de fin estimée : 0:03:20
État d'avancement : 5889 de 68864 effectué(s) ; Étape : 8% ; Total : 2% ; Heure de fin estimée : 0:03:15 .
État d'avancement : 19375 de 68864 effectué(s) ; Étape : 28% ; Total : 9% ; Heure de fin estimée : 0:03:02 ..
État d'avancement : 45313 de 68864 effectué(s) ; Étape : 65% ; Total : 22% ; Heure de fin estimée : 0:00:06 ...
État d'avancement : 68864 de 68864 effectué(s) ; Étape : 100% ; Total : 33% ; Heure de fin estimée : 0:00:04


68864 enregistrements de fichier traités. La vérification des fichiers est terminée.
État d'avancement : 3 de 3 effectué(s) ; Étape : 100% ; Total : 42% ; Heure de fin estimée : 0:00:04 .


3 enregistrements de grand fichier traités. État d'avancement : 0 de 0 effectué(s) ; Étape : 99% ; Total : 42% ; Heure de fin estimée : 0:00:04 ..


0 enregistrements de fichier incorrect traités.
Étape 2 : Examen de la liaison des noms de fichiers...
État d'avancement : 3181 de 74892 effectué(s) ; Étape : 4% ; Total : 44% ; Heure de fin estimée : 0:00:03 ...
État d'avancement : 37878 de 74892 effectué(s) ; Étape : 50% ; Total : 66% ; Heure de fin estimée : 0:00:01
État d'avancement : 69121 de 74892 effectué(s) ; Étape : 92% ; Total : 86% ; Heure de fin estimée : 0:00:01 .
État d'avancement : 69709 de 74892 effectué(s) ; Étape : 93% ; Total : 87% ; Heure de fin estimée : 0:00:01 ..
État d'avancement : 70048 de 74892 effectué(s) ; Étape : 93% ; Total : 88% ; Heure de fin estimée : 0:00:01 ...
État d'avancement : 70258 de 74892 effectué(s) ; Étape : 93% ; Total : 88% ; Heure de fin estimée : 0:00:01
État d'avancement : 70497 de 74892 effectué(s) ; Étape : 94% ; Total : 89% ; Heure de fin estimée : 0:00:01 .
État d'avancement : 70997 de 74892 effectué(s) ; Étape : 94% ; Total : 90% ; Heure de fin estimée : 0:00:01 ..
État d'avancement : 71584 de 74892 effectué(s) ; Étape : 95% ; Total : 91% ; Heure de fin estimée : 0:00:01 ...
État d'avancement : 71850 de 74892 effectué(s) ; Étape : 95% ; Total : 92% ; Heure de fin estimée : 0:00:01
État d'avancement : 74892 de 74892 effectué(s) ; Étape : 100% ; Total : 92% ; Heure de fin estimée : 0:00:01 .


74892 entrées d'index traitées. La vérification des index est terminée.
État d'avancement : 0 de 0 effectué(s) ; Étape : 99% ; Total : 92% ; Heure de fin estimée : 0:00:01 ..


0 fichiers non indexés analysés. État d'avancement : 0 de 0 effectué(s) ; Étape : 99% ; Total : 92% ; Heure de fin estimée : 0:00:01 ...


0 fichiers non indexés récupérés dans le répertoire des fichiers perdus et trouvés.
Étape 3 : Examen des descripteurs de sécurité...
La vérification des descripteurs de sécurité est terminée.
État d'avancement : 0 de 0 effectué(s) ; Étape : 100% ; Total : 99% ; Heure de fin estimée : 0:00:00


3015 fichiers de données traités. CHKDSK vérifie le journal USN...
État d'avancement : 996 de 996 effectué(s) ; Étape : 100% ; Total : 98% ; Heure de fin estimée : 0:00:00 .


8163568 octets USN traités. Vérification du journal USN terminée.

Windows a analysé le système de fichiers sans trouver de problème.
Aucune autre action n'est requise.

62908415 Ko d'espace disque au total.
17639936 Ko dans 18212 fichiers.
3736 Ko dans 3016 index.
0 Ko dans des secteurs défectueux.
144751 Ko utilisés par le système.
65536 Ko occupés par le fichier journal.
45119992 Ko disponibles sur le disque.

4096 octets dans chaque unité d'allocation.
15727103 unités d'allocation au total sur le disque.
11279998 unités d'allocation disponibles sur le disque.
.:NY152:.
Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Re: Rediriger l'invite de commande dans une zone de texte

Message par Ollivier »

@DJes

J'ai comme l'impression qu'on est deux coachs de golfeur autour d'un trou ayant dit "c'est ici les gars! Allez-y, tentez!" et l'on voit les balles de Spock, CaGe, Falsam et NY152 débouler au dessus de nos têtes à 200 km/h.

Les gars, on vous a indiqué où est le trou (DJes avec un code pédagogique inspiré d'Infratec, et moi, avec un tas d'explications).

Avant d'attaquer ChkDsk (ou "pour attaquer ChkDsk"), il FAUT déjà maîtriser, à la fois l'entrée de pipe et la sortie de pipe.

Et le meilleur des cobayes, c'est Cmd.EXE. Falsam s'était bien approché. Mais un petit trop même, puisqu'il a commencé à programmer certaines commandes de l'invite lui-même alors que l'on peut les avoir directement puisque:
1) en maîtrisant ReadProgData, c'est l'affichage complet qu'on récupère
2) en maîtrisant WriteProgData, c'est le clavier que l'on remplace.

Sur une feuille vierge, imaginez le cadran une horloge invisible.
A midi, vous écrivez "Invite Cmd"
A 3H, vous écrivez "lecture"
A 6H, vous écrivez "Gadget"
A 9H, vous écrivez "écriture"

Bravo, vous venez de réaliser le cycle de données entre votre programme (future interface) et Cmd (ou autre, à l'avenir.

Une fois ce cycle fait, il faut poster temporairement des douaniers à 3H pour qu'il trient chaque caractère X$. Si Asc(X$) < 32 Alors Debug Asc(X$).
Ça affiche en debug les codes des caractères système utilisés par le programme (Cmd ou autre) lors de l'affichage.

Ainsi vous testez Chkdsk et vous pouvez poster ici quels codes ont été utilisé (valeur entre 0 et 31).

Je pense que Chkdsk utilise 10, 11 et 13.

Qu'est-ce que vous voyez?
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Re: Rediriger l'invite de commande dans une zone de texte

Message par djes »

Bouh ouh ouh!!!!! (manque vraiment de smileys ce forum bon sang!!!!)

Ollivier a raison mais va trop loin dans les explications. Voici le code refait, qui montre uniquement les lignes terminées par un caractère de passage à la ligne, ce qui désactive l'effet interactif de certains programmes et donc les "doublons".

Faire un CTRL+C dans la console pour stopper le CHKDSK et voir le résultat.

Code : Tout sélectionner

; Based upon code by Infratec
; http://www.purebasic.fr/english/viewtopic.php?f=37&t=64858 
; update by djes to show hidden chars

CompilerIf #PB_Compiler_Unicode = 1
  CompilerWarning "Attention à désactiver l'unicode"
  End
CompilerEndIf

Prog = RunProgram("chkdsk.exe", "", "", #PB_Program_Open|
                                        #PB_Program_Read|#PB_Program_Write|#PB_Program_Ascii)

If Prog
  
  *TempLine = AllocateMemory(256)
  Pos = 0
  MyFinalOutput$ = ""
  
  While ProgramRunning(Prog)
    
    AvailableBytes = AvailableProgramOutput(Prog)
    
    If AvailableBytes > 0
      
      *Buffer = AllocateMemory(AvailableBytes)

      BytesRead = ReadProgramData(Prog, *Buffer, AvailableBytes)
      
      If BytesRead
        
        ;StringA$ = PeekS(*Buffer, BytesRead, #PB_Ascii )
        ;String$ = ""
        
        For i = 0 To BytesRead - 1
          
          b.b = PeekB(*Buffer + i)
          
          Select b
              
            Case $20 To $FF
              ;Caractères "imprimables"
              PokeB(*TempLine + Pos, b)
              Pos + 1
              If Pos > 255
                Pos = 0
              EndIf
              
            Case $0D
              ;Retour chariot
              Pos = 0
              ;Debug "Il se passe des choses..."
              
            Case $0A
              ;Nouvelle ligne
              NewLine$ = PeekS(*TempLine, 256)
              MyFinalOutput$ + NewLine$ + Chr($D) + Chr($A)
              FillMemory(*TempLine, 256)
              Debug NewLine$
              
          EndSelect
          
          ;String$ + Chr(b) + "(" + RSet(Hex(b, #PB_Byte), 2, "0") + ") "
          
        Next i          
        
        FreeMemory(*Buffer)        
        
        ;Debug StringA$
        ;Debug String$
        
      EndIf
      
    EndIf  
    
  Wend
  
  CloseProgram(Prog) 
  FreeMemory(*TempLine)
  
EndIf

MessageRequester("Output", MyFinalOutput$)

End

Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Re: Rediriger l'invite de commande dans une zone de texte

Message par Ollivier »

NY152, si tu nous entends, cligne des yeux...
On va s'en sortir...
Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Re: Rediriger l'invite de commande dans une zone de texte

Message par Ollivier »

Bon, pti père j'espère que ça va quand même...
J'essaierai de faire un petit code à ce sujet si je retouche un ordi.
Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Re: Rediriger l'invite de commande dans une zone de texte

Message par Ollivier »

Bon... Déjà... Etape 1... On va commencer par le commencement :

Documentation de RunProgram

On y récupère l'exemple source de RunProgram dans la doc

Code : Tout sélectionner

 ; Executes the PB compiler with the /? option and displays the output (windows version)
; For Linux/MacOS change the "/?" to "-h".
;
Compiler = RunProgram ( #PB_Compiler_Home +"/Compilers/pbcompiler", "/?", "", #PB_Program_Open | #PB_Program_Read )
Output$ = ""
If Compiler
While ProgramRunning(Compiler)
If AvailableProgramOutput(Compiler)
Output$ + ReadProgramString (Compiler) + Chr (13)
EndIf
Wend
Output$ + Chr (13) + Chr (13)
Output$ + "Exitcode: " + Str ( ProgramExitCode (Compiler))
CloseProgram(Compiler) ; Close the connection to the program
EndIf
MessageRequester("Output", Output$)
En dernière ligne tu remplace :

Code : Tout sélectionner

Output$
par

Code : Tout sélectionner

Std(Output$)
Et tu insères en en-tête cette procédure:

Code : Tout sélectionner

Procedure.S Std(X.S)
Protected Out.S, *X = @X
If #PB_Compiler_Unicode
For I = 0 To (2 * Len(X) ) - 1
Out + Chr(PeekA(*X + I) )
Next
Else
Out = X
EndIf
ProcedureReturn Out
EndProcedure
Ce qui donne :

Code : Tout sélectionner

Procedure.S Std(X.S)
Protected Out.S, *X = @X
If #PB_Compiler_Unicode
For I = 0 To (2 * Len(X) ) - 1
Out + Chr(PeekA(*X + I) )
Next
Else
Out = X
EndIf
ProcedureReturn Out
EndProcedure

 ; Executes the PB compiler with the /? option and displays the output (windows version)
; For Linux/MacOS change the "/?" to "-h".
;
Compiler = RunProgram ( #PB_Compiler_Home +"/Compilers/pbcompiler", "/?", "", #PB_Program_Open | #PB_Program_Read )
Output$ = ""
If Compiler
While ProgramRunning(Compiler)
If AvailableProgramOutput(Compiler)
Output$ + ReadProgramString (Compiler) + Chr (13)
EndIf
Wend
Output$ + Chr (13) + Chr (13)
Output$ + "Exitcode: " + Str ( ProgramExitCode (Compiler))
CloseProgram(Compiler) ; Close the connection to the program
EndIf
MessageRequester("Output", Std(Output$) )
Ce dernier code source te donne-t-il les options offertes par le compilateur?
Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Re: Rediriger l'invite de commande dans une zone de texte

Message par Ollivier »

Ça marche pas?
Répondre