Page 1 sur 1
[R] Lire le stdout d'un programme en direct
Posté : mer. 20 juin 2012 16:17
par TT22
Salut à tous !
Ma question est assez simple, la réponse l'est sûrement moins
Donc, habituellement j'utilise le code suivant pour lire le flux stdout d'un programme :
► Afficher le texte
Code : Tout sélectionner
$PIDProcess = Run('"'&@ScriptDir&'\FSProg.exe"',@ScriptDir, -1, 2)
While 1
$line = StdoutRead($PIDProcess)
If @error Then ExitLoop
MsgBox(0, "STDOUT read:", $line)
WEnd
MsgBox(0, "Debug", "Exiting...")
Mais le problème est que ce script me retourne le contenu du flux seulement lorsque le processus est terminé
Donc, comment pourrais-je faire pour récupérer le stdout d'un programme (en C++) en direct (ne pas devoir attendre la fin du script) ?
PS : Je ne sais pas si ça peut venir du programme dont on veut récupérer le stdout, mais au cas où, les sources du programme C++ sont
ici.
Re: [..] Lire le stdout d'un programme en direct
Posté : mer. 20 juin 2012 16:35
par TommyDDR
Cette technique lit bien la sortie standard pendant l'exécution, si vous ne recevez tout qu'à la fin, c'est que votre exe envoi tout à la fin.
Avez vous testé de lancer le programme par un bon vieux executer / cmd ?
Re: [..] Lire le stdout d'un programme en direct
Posté : mer. 20 juin 2012 16:38
par TT22
TommyDDR a écrit :c'est que votre exe envoi tout à la fin.
Non, mon exe n'envoie pas tout à la fin, il en envoie pendant qu'il est lancé, la preuve c'est que la fenêtre DOS affiche le texte pendant l'exécution du fichier

Re: [..] Lire le stdout d'un programme en direct
Posté : mer. 20 juin 2012 20:09
par TommyDDR
ok je vois, vous affichez votre stdout meme si celui-ci renvoi "" donc pendant que votre msgbox est affiché votre programme est en pause et recevra TOUTES les autres vrais infos une fois que vous aurez cliqué sur OK essayez avec :
Code : Tout sélectionner
$PIDProcess = Run('"'&@ScriptDir&'\FSProg.exe"',@ScriptDir, -1, 2)
While 1
$line = StdoutRead($PIDProcess)
If @error Then ExitLoop
If($line <> "") Then
ConsoleWrite("STDOUT read:" & $line)
EndIf
WEnd
MsgBox(0, "Debug", "Exiting...")
Re: [..] Lire le stdout d'un programme en direct
Posté : mer. 20 juin 2012 20:41
par TT22
Oui, merci ça fonctionne
Edit : Non, en fait ça ne marche pas

Ça me donne toujours tout à la fin.
Re: [..] Lire le stdout d'un programme en direct
Posté : mer. 20 juin 2012 22:52
par TommyDDR
J'ai fait un test avec ca :
Code : Tout sélectionner
$PIDProcess = Run('"'&@ScriptDir&'\testexe.exe"',@ScriptDir, -1, 2)
While 1
$line = StdoutRead($PIDProcess)
If @error Then ExitLoop
If($line <> "") Then
ConsoleWrite("STDOUT read:" & $line)
EndIf
WEnd
MsgBox(0, "Debug", "Exiting...")
En utilisant le programme testexe :
Code : Tout sélectionner
#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Change2CUI=y
#AutoIt3Wrapper_Res_requestedExecutionLevel=asInvoker
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
For $i = 0 To 5
ConsoleWrite("Iteration numero : " & $i & @CRLF)
Sleep(1000)
Next
Et cela marche bien.
Je pense très sérieusement que le "problème" vient de l'exe
Re: [..] Lire le stdout d'un programme en direct
Posté : mer. 20 juin 2012 23:30
par Iste
un simple
Code : Tout sélectionner
#include <Constants.au3>
$PIDProcess = Run(@ComSpec & ' /k ping google.fr -n 100', @SystemDir, @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD)
While 1
$line = StdoutRead($PIDProcess)
If @error Then
ExitLoop
EndIf
MsgBox(0, "STDOUT read:", $line)
WEnd
montre bien la meme chose.
Je pense également que le probleme ne vient pas d'AutoIt
Re: [..] Lire le stdout d'un programme en direct
Posté : mer. 20 juin 2012 23:41
par TT22
TommyDDR a écrit :Je pense très sérieusement que le "problème" vient de l'exe
Peut-être, mais le programme utilise régulièrement des
printf() et en plus lorsqu'on le lance depuis DOS, on voit le stdout s'afficher en temps réel
PS : Le script que tu as donné fonctionne, donc le problème vient bien de l'exe.
Edit : Je viens de voir ton message Iste, et ton script fonctionne bien, mais pas avec mon programme.
Re: [..] Lire le stdout d'un programme en direct
Posté : jeu. 21 juin 2012 05:27
par matwachich
J'ai le même problème, en effet je pense que ça vient du exe.
J'ai créer une DLL en C (MinGW), qui fait des printf de débugage, et quand j'utilise la DLL avec AutoIt, tout m'arrive d'un coup à la fin.
Alors que si j'utilise la DLL dans un autre programme en C, tout est affiché dans la console au bon moment.
Je suis ce sujet de près, si quelqu'un trouve une solution...
Re: [..] Lire le stdout d'un programme en direct
Posté : jeu. 21 juin 2012 07:51
par Tlem
@TT22
Et comme ceci ? :
► Afficher le texte
Code : Tout sélectionner
#include <Constants.au3>
$PIDProcess = Run(@ComSpec & ' /k ping google.fr -n 100', @SystemDir, @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD)
While 1
$line = StdoutRead($PIDProcess)
If @error Then
ExitLoop
EndIf
If $line <> "" Then
ConsoleWrite("STDOUT read: " & $line & @CRLF)
EndIf
Sleep(50)
WEnd
Re: [..] Lire le stdout d'un programme en direct
Posté : jeu. 21 juin 2012 10:26
par TT22
matwachich a écrit :J'ai le même problème
Au moins je ne suis pas tout seul
@ Tlem : Non, toujours le même problème
Je continu à chercher de mon côté dans mon programme qui est censé envoyé le flux.
Re: [..] Lire le stdout d'un programme en direct
Posté : jeu. 21 juin 2012 10:36
par TommyDDR
Iste a écrit :un simple
Code : Tout sélectionner
#include <Constants.au3>
$PIDProcess = Run(@ComSpec & ' /k ping google.fr -n 100', @SystemDir, @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD)
While 1
$line = StdoutRead($PIDProcess)
If @error Then
ExitLoop
EndIf
MsgBox(0, "STDOUT read:", $line)
WEnd
montre bien la meme chose.
Je pense également que le probleme ne vient pas d'AutoIt
Non, à la toute première itération, StdoutRead renverra "" et la msgbox l'affichera, pendant ce temps d'affichage, l'exe continuera à tourner et renvoyer tout plein d'infos c'est seulement quand vous cliquerez sur OK que vous recevrez tout d'un coup. Toutes les fonctions bloquantes sont à proscrire pour du "temps réel".
Re: [..] Lire le stdout d'un programme en direct
Posté : jeu. 21 juin 2012 10:46
par TT22
TommyDDR a écrit :les fonctions bloquantes sont à proscrire pour du "temps réel".
Oui, mais le problème c'est que ça ne fonctionne pas même avec des ConsoleWrite() qui ne bloquent pas le script
Edit : Je viens de voire autre chose : Lorsque j'affiche la console du programme lancé et que j'essaye de lire le stdout avec AutoIt, rien ne s'écrit dans la console
Alors que si je lance le programme sans AutoIt, tout fonctionne.
C'est comme si AutoIt bloquait le stdout du programme jusqu'à la fin.
Re: [..] Lire le stdout d'un programme en direct
Posté : jeu. 21 juin 2012 10:50
par Iste
@TommyDDR : Je ne suis pas si lent que ca ! Ping, surtout en -n 100 prend son temps pour se finir. Aussi, on voit bien les messagesbox se remplir au fur et a mesure.
Je viens de compiler une application C#, pas de problème.
Le problème ne vient donc toujours pas d'AutoIt
► Afficher le textespurces de l'exe
Code : Tout sélectionner
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
for(int i = 0; i < 100; i++) {
Console.WriteLine("ligne" + i);
System.Threading.Thread.Sleep(1000);
}
}
}
}
Re: [..] Lire le stdout d'un programme en direct
Posté : jeu. 21 juin 2012 11:16
par TT22
Ben oui, je pense même que le problème vient de la compilation du programme parce que ce script tout simple en C++ ne fonctionne pas :
► Afficher le texte
Code : Tout sélectionner
#include <iostream>
#include <Windows.h>
using namespace std;
int main(int argc, char *argv[])
{
for (int i=0; i<20; i++)
{
cout << i << "\n";
Sleep(1000);
}
return 0;
}
Donc, ça ne vient pas d'AutoIt, pas du code source du programme. Donc je pense que c'est la compilation.
Je vais aller demander sur un forum spécialisé dans le C++ si ils savent d'où vient le problème. Je vous tiendrais au courant.
Re: [..] Lire le stdout d'un programme en direct
Posté : jeu. 21 juin 2012 12:26
par TT22
Je viens d'obtenir une réponse à ma question (ici :
http://www.cppfrance.com/forum/sujet-FL ... 98326.aspx).
En fait,
printf et
cout n'écrivent pas toujours en direct dans les flux, ça peut se faire par paquets.
Et c'est ce qui se passait lorsqu'on le lançait avec AutoIt.
Il y a donc deux solutions pour envoyer ces flux en temps réel, si on utilise un
printf, il faut utiliser la commande
fflush comme ceci :
► Afficher le texte
Code : Tout sélectionner
#include <iostream>
#include <Windows.h>
using namespace std;
int main(int argc, char *argv[])
{
for (int i=0;i<20;i++)
{
printf("%d\n",i);
[color=#FF0000]fflush(NULL);[/color]
Sleep(1000);
}
return 0;
}
Et si on utilise des
cout, il suffit d'utiliser un
endl, comme ceci :
► Afficher le texte
Code : Tout sélectionner
#include <iostream>
#include <Windows.h>
using namespace std;
int main(int argc, char *argv[])
{
for (int i=0;i<20;i++)
{
cout << i << [color=#FF0000]endl[/color];
Sleep(1000);
}
return 0;
}
Voilà, je passe en [R].
Merci à tous !
Re: [R] Lire le stdout d'un programme en direct
Posté : jeu. 21 juin 2012 15:43
par matwachich
Super!
En plus, je le savait ça! Mais pour les fichiers! C'est une histoire de buffer, un peut comme en AutoIt (FileFlush)
Ce à quoi j'aurai du pensé ce que en C (C++ aussi je pense), un fichier c'est un peut comme la console, c'est un flux!
Ciao