Page 1 sur 1
Décoder les flux standards sous windows (stdin et stdout)
Publié : sam. 02/mai/2020 9:27
par Naheulf
Bonjour,
J'essaye de faire un programme qui prend des données textuelles sur l'entrée standard, fait un traitement dessus, puis recrache le résultat sur la sortie standard.
Une version simplifiée du programme donnerais quelque chose du genre :
Code : Tout sélectionner
If OpenConsole("", )
Define Text$ = Input()
While Text$ <> #PB_Input_Eof
Text$ = UCase(Text$)
PrintN(Text$)
Text$ = Input()
Wend
EndIf
Si j'exécute directement le programme et que saisi des choses dans la console qui s'affiche j’obtiens bien le résultat escompté.
En revanche, si j'essaye de relier l'entrée du programme à la sortie d'un autre via un pipe ça fait juste n'importe quoi.
Pour tester j'utilise la commande suivante :
La sortie normale de la commande ping est :
Code : Tout sélectionner
Envoi d'une requête 'Ping' 127.0.0.1 avec 32 octets de données :
Réponse de 127.0.0.1 : octets=32 temps<1ms TTL=128
Réponse de 127.0.0.1 : octets=32 temps<1ms TTL=128
Réponse de 127.0.0.1 : octets=32 temps<1ms TTL=128
Réponse de 127.0.0.1 : octets=32 temps<1ms TTL=128
Statistiques Ping pour 127.0.0.1:
Paquets : envoyés = 4, reçus = 4, perdus = 0 (perte 0%),
Durée approximative des boucles en millisecondes :
Minimum = 0ms, Maximum = 0ms, Moyenne = 0ms
sauf qu'après passage dans mon programme j'ai ce truc :
Code : Tout sélectionner
??????????????┼????????´????????????????????Q>????´????????????????????????´????????????????????
????´????????????????????????´????????????????????????????┼??????????????????????%??????????????
??????????????????┼┼??????????????????????
Si quelqu'un à une idée de comment régler le problème, je suis preneur.
Note :
J'ai essayé de combiner ReadConsoleData(), PeekS() et PokeS() de différentes façons, je n'arrive jamais à avoir un résultat qui conserve tous les caractères.
Re: Décoder les flux standards sous windows (stdin et stdout
Publié : sam. 02/mai/2020 9:34
par Ar-S
Ce n'est pas une histoire d'unicode, #PB_UTF8 etc avec ton openconsole et ton exe ? (avec les flag #PB_Unicode , #PB_UTF8 etc) ?
Re: Décoder les flux standards sous windows (stdin et stdout
Publié : sam. 02/mai/2020 9:51
par Naheulf
Bah j'ai testé mais j'ai pas réussi.
Le plus proche que j'ai réussi à faire c'est avec un code du genre :
Code : Tout sélectionner
If OpenConsole("")
#BUFFER_SIZE = 1024
*Buffer = AllocateMemory(#BUFFER_SIZE)
ReadSize = ReadConsoleData(*Buffer, #BUFFER_SIZE)
While ReadSize
Text$ = PeekS(*Buffer, ReadSize, #PB_Ascii)
Text$ = UCase(Text$)
PrintN(Text$)
ReadSize = ReadConsoleData(*Buffer, #BUFFER_SIZE)
Wend
EndIf
Sauf que ça ne garde pas non plus tous les caractères... (mais dans ce cas, on est cohérent entre une exécution direct et un exécution avec des pipes)
Le texte :
Donne :
Re: Décoder les flux standards sous windows (stdin et stdout
Publié : sam. 02/mai/2020 10:46
par GallyHC
Code : Tout sélectionner
If OpenConsole("")
#BUFFER_SIZE = 1024
*Buffer = AllocateMemory(#BUFFER_SIZE)
ReadSize = ReadConsoleData(*Buffer, #BUFFER_SIZE)
While ReadSize
Text$ = PeekS(*Buffer, ReadSize, #PB_Ascii)
;Text$ = UCase(Text$)
PrintN(Text$)
ReadSize = ReadConsoleData(*Buffer, #BUFFER_SIZE)
Wend
EndIf
Re: Décoder les flux standards sous windows (stdin et stdout
Publié : sam. 02/mai/2020 11:52
par Naheulf
En fait t'as juste commenté la partie "utile" du code (la fonction UCase() qui représente le traitement que doit faire le programme).
Le cœur du problème reste intact : certains caractères ne sont pas conservés (ex : "ê" devient "^", UCase ou non). Donc si ces caractères visibles deviennent n'importe quoi, je n'ose imaginer ce qu'il se passera sur les caractères de contrôles (dont le traitement est le but du programme complet).
Re: Décoder les flux standards sous windows (stdin et stdout
Publié : sam. 02/mai/2020 19:40
par Kwai chang caine
Je ne sais pas si c'est ce que tu cherches car c'est juste pour windows,
Mais y'a ce code de ZORRO qui marche sous W10, j'ai vérifié
http://www.purebasic.fr/french/viewtopi ... 93#p192393
Code : Tout sélectionner
prg=RunProgram("cmd.exe", "/c ipconfig /all ", "", #PB_Program_Open|#PB_Program_Read) ; la commande "ipconfig /all" est entré dans la console
If prg
While ProgramRunning(prg)
If AvailableProgramOutput(prg)
sOEM_in_unicode.s = ReadProgramString(prg, #PB_Ascii)
iByteLength = Len(sOEM_in_unicode) + 2
sOem_in_Ascii.s = Space(iByteLength)
PokeS(@sOem_in_Ascii, sOEM_in_unicode, -1, #PB_Ascii)
sUnicode.s = Space(iByteLength)
OemToChar_(@sOem_in_Ascii, @sUnicode)
Sortie$=Sortie$+sUnicode.s+Chr(10)+Chr(13)
EndIf
Wend
Sortie$ + Chr(10) + Chr(13)
Sortie$ + "Code de retour : " + Str(ProgramExitCode(prg))
CloseProgram(prg) ; Ferme la connection vers le programme
EndIf
MessageRequester("Sortie", Sortie$)
qui donne
Console a écrit :
Utilisation : ping [-t] [-a] [-n count] [-l size] [-f] [-i TTL] [-v TOS]
[-r count] [-s count] [[-j host-list] | [-k host-list]]
[-w timeout] [-R] [-S srcaddr] [-c compartment] [-p]
[-4] [-6] nom_cible
Options :
-t Effectue un test ping sur l'hôte spécifié jusqu'à son arrêt.
Pour afficher les statistiques et continuer,
appuyez sur Ctrl+Attn.
Pour arrêter, appuyez sur Ctrl+C.
-a Résout les adresses en noms d'hôtes.
-n count Nombre de demandes d'écho à envoyer.
-l size Taille du tampon d'envoi.
-f Active l'indicateur Ne pas fragmenter dans le paquet (IPv4
uniquement).
-i TTL Durée de vie.
-v TOS Type de service (IPv4 uniquement. La
configuration de ce paramètre n'a aucun effet sur le type
de service dans l'en-tête IP).
-r count Itinéraire d'enregistrement du nombre de sauts (IPv4
uniquement).
-s count Horodatage du nombre de sauts (IPv4 uniquement).
-j host-list Itinéraire source libre parmi la liste d'hôtes (IPv4
uniquement).
-k host-list Itinéraire source strict parmi la liste d'hôtes (IPv4
uniquement).
-w timeout Délai d'attente pour chaque réponse, en millisecondes.
-R Utilise l'en-tête de routage pour tester également
l'itinéraire inverse (IPv6 uniquement).
D'après la RFC 5095, l'utilisation de cet en-tête de routage
est déconseillée. Certains systèmes peuvent supprimer des
demandes d'écho si cet en-tête est utilisé.
-S srcaddr Adresse source à utiliser.
-c compartment Identificateur de compartiment de routage.
-p Effectue un test ping sur l'adresse de fournisseur
de la virtualisation réseau Hyper-V.
-4 Force l'utilisation d'IPv4.
-6 Force l'utilisation d'IPv6.
Code de retour : 1
Re: Décoder les flux standards sous windows (stdin et stdout
Publié : dim. 03/mai/2020 9:00
par Naheulf
Merci Kwai chang caine.
Gally m'as donné une solution
sur discord et j'ai oublié de faire le retour sur le fofo
En fait tu lis dans mes pensées. Ta solution (enfin celle de Zorro) ne correspond pas à ce que je voulais faire pour ce programme : elle correspond à ce que je voulais faire pour une seconde variante du programme (qui utiliserait effectivement l'appel à un sous programme)
Reste à voir si je vais avoir le droit à d'autres "surprises" comme le caractère de contrôle "ESC" qui se transforme en '←' avec OemToCharW()...
Re: Décoder les flux standards sous windows (stdin et stdout
Publié : dim. 03/mai/2020 12:24
par TazNormand
@Naheulf : peux-tu poster ici la solution que t'a donné GallyHC sur Discord, car elle pourrait servir à quelqu'un d'autre plus tard. Merci
Re: Décoder les flux standards sous windows (stdin et stdout
Publié : dim. 03/mai/2020 15:06
par GallyHC
Voila:
Code : Tout sélectionner
If OpenConsole("", #PB_Ascii)
#BUFFER_SIZE = 1024
Text$ = Space(#BUFFER_SIZE)
*Buffer = AllocateMemory(#BUFFER_SIZE)
ReadSize = ReadConsoleData(*Buffer, #BUFFER_SIZE)
While ReadSize
OemToChar_(*Buffer, @Text$)
PrintN((Mid(Text$, 1, ReadSize - 2)))
ReadSize = ReadConsoleData(*Buffer, #BUFFER_SIZE)
Wend
EndIf