Re: Rediriger l'invite de commande dans une zone de texte
Publié : dim. 28/févr./2016 23:40
Mais je suis sur mobile (55% de batterie).
Forums PureBasic - Français
http://forums.purebasic.com/french/
Ben non... Mauvaise approche...Falsam a écrit :Le temps que tu passes pour commenter ce que je fais et me poser des question en mp que tu pourrais trés
bien poser sur le forum, t'aurais permis de tester et de poster ton code.
Apparemment, tu dois être fatigué. Il n'y a qu'une question en 6 mois de temps...En mp, moi y'en a écrit :Salut Falsam,
j'ai du mal à saisir les raisons pour lesquelles tu reproduis les commandes de Cmd.EXE.
Est-ce que l'échange de données (ReadProgramData) reste muet?
Olliv
Code : Tout sélectionner
Data.S "00c700fc00e900e200e400e000e500e700ea00eb00e800ef00ee00ec00c400c5"
Data.S "00c900e600c600f400f600f200fb00f900ff00d600dc00a200a300a520a70192"
Data.S "00e100ed00f300fa00f100d100aa00ba00bf231000ac00bd00bc00a100ab00bb"
Data.S "259125922593250225242561256225562555256325512557255d255c255b2510"
Data.S "25142534252c251c2500253c255e255f255a25542569256625602550256c2567"
Data.S "2568256425652559255825522553256b256a2518250c25882584258c25902580"
Data.S "03b100df039303c003a303c300b503c403a6039803a903b4221e03c603b52229"
Data.S "226100b1226522642320232100f7224800b0221900b7221a207f00b225a000a0"
Code : Tout sélectionner
If AvailableBytes > 1024
...
EndIf
If AvailableBytes
...
Etc (Lecture du flux)
...
EndIf
Code : Tout sélectionner
Available = AvailableBytes
While Available > MemorySize(*Buffer) Or Available
If Available < 0
Error("Consigne de taille de flux inadéquate au flux reçu")
Else
...
Etc (Lecture du flux)
...
EndIf
Available - BytesRead
Wend
Code : Tout sélectionner
; by Infratec
; http://www.purebasic.fr/english/viewtopic.php?f=37&t=64858
*Buffer = AllocateMemory(1024)
If *Buffer
Prog = RunProgram("cmd", "", "", #PB_Program_Open|
#PB_Program_Read|#PB_Program_Write|#PB_Program_Ascii)
If Prog
While ProgramRunning(Prog)
AvailableBytes = AvailableProgramOutput(Prog)
If AvailableBytes
If AvailableBytes > 1024
AvailableBytes = 1024
EndIf
BytesRead = ReadProgramData(Prog, *Buffer, AvailableBytes)
If BytesRead
String$ = PeekS(*Buffer, BytesRead, #PB_Ascii)
Debug String$
If FindString(String$, ")")
Debug "Input required"
Debug "Sending CR in 3 seconds"
Delay(3000)
Debug "Sended"
WriteProgramStringN(Prog, "")
EndIf
EndIf
EndIf
Delay(10)
Wend
CloseProgram(Prog)
EndIf
FreeMemory(*Buffer)
EndIf
Ca n'a pas du être facile de taper ton commentaire depuis ton téléphone mobile.Ollivier a écrit :C'est muet ou ça donne quelquechose?
Pour des commandes classiques types dir, ipconfig, etc... ton code ou le mien, ça ne change rien.Microsoft Windows [version 10.0.10240]
(c) 2015 Microsoft Corporation. Tous droits r‚serv‚s.
C:\Program Files (x86)\PureBasic542>
Input required
Sending CR in 3 seconds
Sended
C:\Program Files (x86)\PureBasic542>
Input required
Sending CR in 3 seconds
Code : Tout sélectionner
For I = 1 To n
Read.I x ; ou tout autre système d'appel de caractère
; par exemple, ce que l'on détecte de changé dans
; EditorGadget ou un shortcut, etc...
PokeA(*Buffer + I -1, x)
Next
WriteProgramData(Prog, *Buffer, n)
Comme je l'expliquais, on se retrouve avec des lignes en doublon. Alors que dans l'invite de commande ceci n'est qu'une seule ligne. Ca fait pas propre.cage a écrit :J'ai essayé la commande chkdsk avec la méthode clip et cela fonctionneJ'ai coché la case Request Administrator mode for Windows Vista and aboveCode : 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()
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.
Ca c'est très bien quand on sait quoi chercher. Comme je veux une redirection d'un invite de commande, virtuellement, n'importe quel programme pourrait être passé donc c'est infiltrable.Ollivier a écrit :Si si, il sait le faire!NY152 a écrit :Est-ce PureBasic sait le faire. Aucune idée.
Entraine-toi avec un EditorGadget().
Tu lui colles 3 lignes :
"lundi"
"mardi"
"mercredi"
Le tout est de savoir si tu vas juste modifier la dernière ligne ("mercredi") ou bien si tu auras besoin de modifier les autres lignes.
Mon avis porte sur un tableau de chaînes ou une liste chaînée de chaînes qui servira de mémoire à ton affichage.
La subtilité réside dans le code de fin de ligne qui peut être:
- chr(10)
- chr(13)
- chr(13) + chr(10)
- chr(10) + chr(13)
C'est à vérifier une bonne fois pour toute pour EditorGadget() d'abord. (Après tu regarderas le code de fin de ligne de ta sortie de console)
Tu fais une procédure qui copie le tableau vers l'EditorGadget()
Ex : RefreshList()
Ensuite tu fais 4 fonctions pour gérer ce tableau de chaîne à partir de ta sortie de console.
Ex:
Clear_List() ; vide le tableau
Add_List(a$) ; Ajoute une ligne en fin de liste
Modify_List(a$) ; Change la dernière ligne
Grow_List(a$) ; Ajoute quelquechose en fin de dernière ligne
Là, toute la partie "Tableau vers EditorGadget()" est pensée.
Reste la partie "Console vers Tableau".
Il s'agit d'une lecture caractère par caractère de chaque chaîne de sortie de console (la console est un exemple de programme).
Ça semble lourd mais ce n'est pas bien compliqué.
Chaque caractère est extrait avec Mid(), converti en valeur de code ASCII avec a = Asc().
Par défaut, l'on affiche les caractères donc :
a$ + chr(a)
C'est le cas quand a > 31.
Si c'est un caractère système (a < 32), on suit les quelques règles ASCII ancestrales:
7 émet un signal sonore
9 tabulation
10 va en ligne suivante
12 efface l'écran
13 va en début de ligne
Il reste 3 codes à chercher dans la table ASCII dispo dans l'éditeur PureBasic :
- Aller en ligne précédente
- Aller en colonne précédente (équivalent d'une touche gauche)
- Aller en colonne suivante.
Quelque soit le code ASCII, le résultat pourra être traité par l'une des quatres fonctions Blabla_List() créées plus haut!
Après ça... Rien de plus, tout marchera!
Excellent code mais même symptome : Y a des lignes multiplié (et y a pas de retour à la ligne pour les lignes doublées en plus). Eviter de "bug" doit être possible, les devs de TakeCommand y sont arrivé eux ^^falsam a écrit :Ce code à compiler redirige l'invite de commande dans un GadgetEditor().
Vous allez pouvoir saisir les commandes console directement dans l'éditeur. Vous devez être sur la dernière ligne de l'éditeur.
Les flèches haut et bas ne sont pas opérationnelles.
Attention certaines commandes comme TIME sont bloquantes.
Essayer les commandes de gestion de dossiers comme CD, MD, etc .... un dir >result.txt fonctionne.
Les commandes ipconfig, ping, net start, help, etc .... fonctionnent.
N'oubliez pas ! ce code est loin d’être fonctionnel.Code : Tout sélectionner
;Terminal : Rediriger l'invite de commande dans un gadget Enumeration Font #FontGlobal EndEnumeration Enumeration Window #MainForm EndEnumeration Enumeration Gadget #Result EndEnumeration Enumeration KeyBoard #Up #Down #Return EndEnumeration Global Dim Cmds.s(0), Index.i Declare Start() Declare RunCmd(Cmd.s) Declare OnReturn() Declare OnKey() Declare OnResize() Start() Procedure Start() LoadFont(#FontGlobal, "", 11) SetGadgetFont(#PB_Default, FontID(#FontGlobal)) If OpenWindow(#MainForm, 0, 0, 800, 600, "Terminal", #PB_Window_SystemMenu|#PB_Window_ScreenCentered|#PB_Window_SizeGadget) EditorGadget(#Result, 5, 10, 790, 580) SetGadgetColor(#Result, #PB_Gadget_BackColor, RGB(174, 191, 191)) SetActiveGadget(#Result) AddKeyboardShortcut(#MainForm, #PB_Shortcut_Up, #Up) AddKeyboardShortcut(#MainForm, #PB_Shortcut_Down, #Down) AddKeyboardShortcut(#MainForm, #PB_Shortcut_Return, #Return) BindEvent(#PB_Event_Menu, @OnKey(), #MainForm, #Up) BindEvent(#PB_Event_Menu, @OnKey(), #MainForm, #Down) BindEvent(#PB_Event_Menu, @OnReturn(), #MainForm, #Return) BindEvent(#PB_Event_SizeWindow, @OnResize()) ;BindGadgetEvent(#Result, @OnChange(), #PB_EventType_Change) RunCmd("echo Bienvenue ...") RunCmd("cd") ;Affiche le dossier courrant Repeat : Until WaitWindowEvent(10) = #PB_Event_CloseWindow EndIf EndProcedure Procedure RunCmd(Cmd.s) Protected prg.i, Stdout.s, TagResult.b Select LCase(cmd) Case "cls" ClearGadgetItems(#Result) Case "exit" End Default If LSet(Cmd, 2) = "cd" SetCurrentDirectory(Trim(Mid(cmd, 3))) AddGadgetItem(#Result, -1, "Le dossier courrant est : " + GetCurrentDirectory()) ElseIf LCase(LSet(cmd, 5)) = "title" SetWindowTitle(#MainForm, Trim(Mid(cmd, 6))) Else prg = RunProgram("cmd.exe", "/C echo|CHCP 65001| " + Cmd, "", #PB_Program_Open|#PB_Program_Read|#PB_Program_Write|#PB_Program_Hide) If prg While ProgramRunning(prg) If AvailableProgramOutput(prg) TagResult = #True Stdout = ReadProgramString(prg) AddGadgetItem(#Result, -1, Stdout) EndIf Wend CloseProgram(prg) If FindString(Cmd, ">") Or FindString(LCase(Cmd), "del") TagResult = #True EndIf If Not TagResult AddGadgetItem(#Result, -1, "Erreur de commande : " + Cmd) EndIf EndIf EndIf AddGadgetItem(#Result, -1, "") EndSelect EndProcedure Procedure OnReturn() Protected Buffer.s = GetGadgetItemText(#Result, CountGadgetItems(#Result)-1) SetGadgetState(#Result, CountGadgetItems(#Result)-1) If Trim(Buffer)<>"" Index = ArraySize(Cmds()) Cmds(Index) = Buffer ReDim Cmds(Index + 1) RunCmd(Buffer) Else AddGadgetItem(#Result, -1, "") EndIf SetGadgetState(#Result, CountGadgetItems(#Result)-1) EndProcedure ;Obliger le curseur de saisie à rester sur la derniere ligne de l'éditeur ;Fleche bas, haut Procedure OnKey() SetGadgetState(#Result, CountGadgetItems(#Result) - 1) Select EventMenu() Case 0 ;Fleche haut If Index < ArraySize(Cmds()) Index + 1 EndIf Case 1 ;Fleche bas If index > 0 Index - 1 EndIf EndSelect SetGadgetItemText(#Result, CountGadgetItems(#Result) - 1, Cmds(Index)) EndProcedure Procedure OnResize() Protected Width = WindowWidth(#MainForm) Protected Height= WindowHeight(#MainForm) ResizeGadget(#Result, #PB_Ignore, #PB_Ignore, Width - 10, Height - 20) EndProcedure
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
Prog = RunProgram("chkdsk.exe", "", "", #PB_Program_Open|
#PB_Program_Read|#PB_Program_Write|#PB_Program_Ascii)
If Prog
Debug "ok"
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)
String$ + Chr(b) + "(" + RSet(Hex(b, #PB_Byte), 2, "0") + ") "
Next i
FreeMemory(*Buffer)
Debug StringA$
Debug String$
EndIf
EndIf
Wend
CloseProgram(Prog)
EndIf
Si si il sert. Enfin peut êtredjes a écrit :Et mon code, il ne sert à rien ?
Il parle bien d'un programme quelconque en invite de commande !!NY152 a écrit :J'aimerais pouvoir "détourner" l'affichage d'un programme en invite de commande vers une zone de texte au sein d'une interface.
un seul caractère changeait sur une ligne ?NY152 a écrit :En effet, j'ai déjà vu des codes mais il faisait tout un tas de "doublons" de lignes (alors qu'un seule caractère changeait sur une ligne). En gros, je ne veut pas le stdout tout bête mais le "vraie affichage" que reçoit l'invite de commande.