Redirection sortie

Résolu
M5i9k Messages postés 49 Date d'inscription mardi 22 novembre 2005 Statut Membre Dernière intervention 10 novembre 2007 - 2 août 2006 à 17:06
M5i9k Messages postés 49 Date d'inscription mardi 22 novembre 2005 Statut Membre Dernière intervention 10 novembre 2007 - 3 août 2006 à 01:39
Bonjour à tous,

je voudrais lire la sortie d'une console lancée à partir de mon programme (j'utilise CreateProcess), je voudrais savoir si je suis sur la bonne route voici comment je m'y prend :

int _tmain(int argc, _TCHAR* argv[])
{
    char *lpExeName = "prog.exe";
    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    HANDLE hFile;
    char buffer[4096];
    DWORD dwReaded;

    hFile = CreateFile("data.txt", FILE_ALL_ACCESS, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    if(!hFile)
        cout << "Erreur de creation de fichier";

    ZeroMemory(&si, sizeof(si));
    si.cb = sizeof(si);
    si.dwFlags = STARTF_USESTDHANDLES;
    si.hStdOutput = hFile;

    ZeroMemory(&pi, sizeof(pi));

    if(!CreateProcess(lpExeName, "/c dir", NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
        cout << "Erreur de creation de processus!";

    if(!ReadFile(hFile, buffer, sizeof(buffer), &dwReaded, NULL))
        cout << "Erreur de lecture du flux";

    buffer[dwReaded] = '\0';

    cout << "Octets lus : " << dwReaded << endl << buffer;

    if(hFile)
        CloseHandle(hFile);

    return 0;
}

En gros je crée un fichier pour enregistrer la sortie de la console, avec si.hStdOutput je redirige la sortie du processus vers le fichier (je suppose), et ensuite je tente d'afficher la sortie en lisant le fichier, mais le problème est que dwReaded vaut toujours 0, ça me donne donc "Octets lus : 0", je ne comprends pas pourquoi... Le programme conpile sans erreur et il n'y à pas d'erreur lors de l'execution. Si quelqu'un pourrait me dire où se trouve l'erreur... Merci d'avance.

17 réponses

M5i9k Messages postés 49 Date d'inscription mardi 22 novembre 2005 Statut Membre Dernière intervention 10 novembre 2007
3 août 2006 à 01:26
C'est bon j'ai trouvé ma couille!! C'est au niveau de CreateProcess(...FALSE..) doit être TRUE pour hériter les handles .
Résultat : dwRead > 0

Merci beaucoup pour ton aide vecchio56
3
wxccxw Messages postés 755 Date d'inscription samedi 15 mai 2004 Statut Membre Dernière intervention 30 janvier 2011
2 août 2006 à 17:54
tu ne pourai pas faire un hook de la fonction de fermeture et  l'intercepter
0
M5i9k Messages postés 49 Date d'inscription mardi 22 novembre 2005 Statut Membre Dernière intervention 10 novembre 2007
2 août 2006 à 21:31
euh, oui j'aimerais savoir hooker les fonctions mais c'est encore trop compliqué pour moi , sinon je ne vois pas comment récuperer le texte de la console en fesant cela, est-ce que tu pourrais detailler ton idée ?
0
vecchio56 Messages postés 6535 Date d'inscription lundi 16 décembre 2002 Statut Membre Dernière intervention 22 août 2010 14
2 août 2006 à 22:24
Tu peux utiliser des Pipes

_____________________________________
Un éditeur de ressources gratuit pour Windows
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
M5i9k Messages postés 49 Date d'inscription mardi 22 novembre 2005 Statut Membre Dernière intervention 10 novembre 2007
2 août 2006 à 22:35
Ok, j'avais déja essayer les pipes mais ça me paraissait compliqué je vais reessayer en lisant l'aide. Merci pour le lien.
0
vecchio56 Messages postés 6535 Date d'inscription lundi 16 décembre 2002 Statut Membre Dernière intervention 22 août 2010 14
2 août 2006 à 22:38
Les pipes sont faits précisément pour ca, tu devrais donc pas trouver plus simple

_____________________________________
Un éditeur de ressources gratuit pour Windows
0
M5i9k Messages postés 49 Date d'inscription mardi 22 novembre 2005 Statut Membre Dernière intervention 10 novembre 2007
3 août 2006 à 00:22
Voici mon ancien code avec les tubes (pipes) :

    char *lpExeName = "prog.exe";
    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    HANDLE hOutput, hInput;
    DWORD dwReaded;
    char buffer[4096];

    if(!CreatePipe( &hOutput, &hInput, NULL, 0))
        cout << "Erreur de création de pipe";

    ZeroMemory(&si, sizeof(si));
    si.cb = sizeof(si);
    si.dwFlags = STARTF_USESTDHANDLES;
    si.hStdOutput = hOutput;
    si.hStdInput = hInput;

    ZeroMemory(&pi, sizeof(pi));

    if(!CreateProcess(lpExeName, "/c dir", NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
        cout << "Erreur de creation de processus!";

    if(!FlushFileBuffers(hOutput))
        cout << "Erreur Flush()";
    if(!ReadFile(hOutput, buffer, 15, &dwReaded, NULL))
        cout << "Erreur de lecture du flux";

    if(hOutput)
        CloseHandle(hOutput);
    if(hInput)
        CloseHandle(hInput);

le problème est que le programme se bloque au niveau de ReadFile(...) je ne comprends pas pourquoi, j'ai donc ajouté FlushFileBuffers(...) mais sa n'a rien changé...
0
vecchio56 Messages postés 6535 Date d'inscription lundi 16 décembre 2002 Statut Membre Dernière intervention 22 août 2010 14
3 août 2006 à 00:39
Je crois que tu te mélanges les pinceaux
Déja soyons logique, on inverse les deux premiers arguments de CreatePipe:
CreatePipe(&hInput, &hOutput, NULL, 0);
si.hStdOutput = hOutput; // OK, le processus va écrire dans le tube
si.hStdInput = hInput; // si on fait ca le processus va lire le tube, il ne faut pas

Et la lecture doit se faire sur hInput: ReadFile(hInput, ...)
Tu peux aussi enlever FlushFileBuffers

Enfin, petit détail, read est un verbe irrégulier, et le participe passé est read (qu'on prononce red). Tu devrais donc appeler ta variable dwRead et non dwReaded (on a quand même 231 réponses dans google pour dwReaded) (oui j'ai que ça a faire de chercher)

_____________________________________
Un éditeur de ressources gratuit pour Windows
0
M5i9k Messages postés 49 Date d'inscription mardi 22 novembre 2005 Statut Membre Dernière intervention 10 novembre 2007
3 août 2006 à 00:56
Mdrrrrrrr


Ok j'ai modifié mon code pour mettre dwRead , par contre je ne comprends pas trop le fonctionnement des tubes :
On écrit dans la sortie(hOutput) et on lit dans l'entrée(hInput)? ou plutôt écrire dans l'entrée et lire dans la sortie ?
Je pense que le processus crée écrit dans la sortie du tube donc dans hOutput et donc c'est bien hOutput que je dois lire non? Car pour moi, hInput correspond à l'entrée donc le clavier par exemple.

CreatePipe( PHANDLE hReadPipe, PHANDLE hWritePipe...)
hReadPipe Sortie, hWritePipe Entrée ou le contraire???

En remplaçant tout sa, j'ai toujours le même problème : le programme bloque sur ReadFile().
0
vecchio56 Messages postés 6535 Date d'inscription lundi 16 décembre 2002 Statut Membre Dernière intervention 22 août 2010 14
3 août 2006 à 01:04
CreatePipe
Le premier param est le pipe de lecture (celui dans lequel on va lire). Le deuxième est celui dans lequel on écrit. En l'occurence ce n'est pas nous qui écrivons mais un autre processus, c'est pourquoi on lui affecte cet handle comme sortie. Mais je t'accorde que ça peut être difficile de s'y retouver par moment. Je m'y suis moi même repris à deux fois avant d'écrire ce message.
Autre chose: quand je faisait un CreatePipe, je spécifiais aussi le troisième argument (SECURITY_ATTRIBUTES sa = {sizeof sa, NULL, 1};) Je sais pas si c'est obligatoire...

Pour être clair: le ReadFile doit se faire sur le premier param, et l'autre processus doit écrire dans le deuxième (après tu appelles tes HANDLEs comme tu le souhaites).

_____________________________________
Un éditeur de ressources gratuit pour Windows
0
vecchio56 Messages postés 6535 Date d'inscription lundi 16 décembre 2002 Statut Membre Dernière intervention 22 août 2010 14
3 août 2006 à 01:06
Pour répondre à ta question:hReadPipe Sortie, hWritePipe Entrée en effet

Mais l'entrée du tube = la sortie de l'autre processus

_____________________________________
Un éditeur de ressources gratuit pour Windows
0
M5i9k Messages postés 49 Date d'inscription mardi 22 novembre 2005 Statut Membre Dernière intervention 10 novembre 2007
3 août 2006 à 01:21
ah oui je crois y voir plus clair :


si.hStdOutput = Sortie de l'autre processus


si.hStdInput = Entrée de l'autre processus ( si je désire communiquer avec )


donc dans mon cas je n'utilise que hStdOutput pour rediriger la sortie du processus sur l'entrée du tube (hOutput), et je lis dans la sortie du tube (hInput) le résultat.

->TEST...
-> sa bloque toujours sur ReadFile voici mon code :



char
*lpExeName = "Prog.exe";
STARTUPINFO si;
PROCESS_INFORMATION pi;
SECURITY_ATTRIBUTES sa;
HANDLE hSortieTube, hEntreeTube;
DWORD dwRead;
char buffer[4096];


sa.bInheritHandle = TRUE;
sa.lpSecurityDescriptor = 0;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);



if(!CreatePipe( &hSortieTube, &hEntreeTube, &sa, 0))
   cout << "Erreur de création de pipe";


ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
si.dwFlags = STARTF_USESTDHANDLES;
si.hStdOutput = hEntreeTube;
ZeroMemory(&pi, sizeof(pi));



if(!CreateProcess(lpExeName, "/c dir", NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
   cout << "Erreur de creation de processus!";



if(!ReadFile(hSortieTube, buffer, sizeof(buffer), &dwRead, NULL))
   cout << "Erreur de lecture du flux";

cout << "Octets lus : " << dwRead;



if(hEntreeTube)
   CloseHandle(hEntreeTube);



if(hSortieTube)
   CloseHandle(hSortieTube);
0
vecchio56 Messages postés 6535 Date d'inscription lundi 16 décembre 2002 Statut Membre Dernière intervention 22 août 2010 14
3 août 2006 à 01:26
-CreateProcess(lpExeName, "/c dir", 0, 0, TRUE, NORMAL_PRIORITY_CLASS, 0, 0, &si, &pi);
-Vérifie que ton processus écrit au moins 15 octets (je tente on sait jamais)

_____________________________________
Un éditeur de ressources gratuit pour Windows
0
vecchio56 Messages postés 6535 Date d'inscription lundi 16 décembre 2002 Statut Membre Dernière intervention 22 août 2010 14
3 août 2006 à 01:28
Ah ben j'avais trouvé aussi! C'est bon on s'en est sortis!

_____________________________________
Un éditeur de ressources gratuit pour Windows
0
M5i9k Messages postés 49 Date d'inscription mardi 22 novembre 2005 Statut Membre Dernière intervention 10 novembre 2007
3 août 2006 à 01:29
Oui, 46 octets par contre j'ai un autre problème maintenant, sachant que le processus écrit plusieurs ligne, je suppose que ReadFile s'arrête des qu'il trouve un caractère de retour à la ligne, y à t'il une autre fonction qui permet de lire tout le flux???
0
vecchio56 Messages postés 6535 Date d'inscription lundi 16 décembre 2002 Statut Membre Dernière intervention 22 août 2010 14
3 août 2006 à 01:31
Non non, ReadFile lit le nombre de caractères demandés, saut de ligne ou pas

_____________________________________
Un éditeur de ressources gratuit pour Windows
0
M5i9k Messages postés 49 Date d'inscription mardi 22 novembre 2005 Statut Membre Dernière intervention 10 novembre 2007
3 août 2006 à 01:39
Okok merci
0
Rejoignez-nous