IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Lazarus Pascal Discussion :

Problème de Input.Write(); avec un TProcess


Sujet :

Lazarus Pascal

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 14
    Par défaut Problème de Input.Write(); avec un TProcess
    Bonjour à tous et toutes,

    Le problème est le suivant:

    J'ai un programme (un binaire sans code source dont je ne suis pas l'auteur) qui fonctionne dans un terminal. Une fois lancé, la seule manière de l'arrêter est de tapper "quit" dans le terminal. Ce programme fonctionne parfaitement bien et se termine lors de l'envois de cette commande "quit" sur le stdin...

    Pour les besoins d'un projet (une sorte de GUI) je dois lancer ce programme depuis une autre application, j'utilise pour cela un TProcess. Actuellement j'arrive a lancer mon programme, récupérer la sortie stdout et traiter les retours. Mais la ou je coince c'est lorsque j'essaye de fermer mon programme, vu que je ne peux le fermer proprement que par l'envoie de la commande "quit" en stdin ! En effet la fonction de TProcess permettant de le faire ne semble pas fonctionner ! Pourtant aucun message d'erreur n'est généré et le code (aussi loin que je suis remonté dans les ancètres du TProcess et des TInputPipeStream et TOutputPipeStream) semble correctement écrit... Mais rien ne se passe...

    Si quelqu'un a déjà rencontré ce problème ou si quelqu'un a une solution, je suis preneur !

    Quelques infos:
    FPC v2.2.2
    LAZARUS v0.9.26(beta)
    OS Linux
    FONCTION UTILISÉE TProcess.Input.Write(const Buffer; Count: Longint): Longint:

    PARTIE DU CODE:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    procedure TMyProcess.WriteLine(const A_String: String);
    begin
      if (Length(A_String) > 0) then
        Input.Write(A_String[1], Length(A_String));
    end;
    APPELÉE PAR:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    const
      CRLF = #10;
      ...
      MyProcess.WriteLine('quit' + CRLF);

  2. #2
    Membre chevronné

    Inscrit en
    Avril 2003
    Messages
    284
    Détails du profil
    Informations forums :
    Inscription : Avril 2003
    Messages : 284
    Par défaut
    Bonjour,

    Tu as du partir du code suivant:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    procedure TMultipleProcessDemoForm.SendInput(Process:TProcess;InputMemo:TMemo);
    var
      InputStrings: string;
    begin
      if Process.Running then begin
        InputStrings := InputMemo.Lines.Text;
        Process.Input.Write(InputStrings[1], length(InputStrings));
      end;
    end;
    portion de code issu d'un exemple pris ici :

    https://lazarus-ccr.svn.sourceforge....amples/process

    dans ce code, InputStrings[1], représente une ligne complète

    mais dans ton code, A_String[1] n'envoie qu'un seul caractère de ta string.

    Tu devrais plutôt essayer:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    procedure TMyProcess.WriteLine(const A_String: String);
    begin
      if (Length(A_String) > 0) then
        Input.Write(A_String, Length(A_String));
    end;
    Bonne continuation

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 14
    Par défaut
    Bonjour et merci de ta réponse.

    Effectivement,mon code était éroné comme tu l'as souligné, mais malheureusement, même après modification, les commandes envoyées ne passent pas...

    Par ailleurs, j'ai testé l'exemple que tu cites (celui fourni avec Lazarus) avec mon programme, et les commandes passées ne sont pas prises en compte non plus !

    Qué passa ?

    Je commence à me demander si le programme que j'essaye de contrôler n'a pas une gestion des entrées clavier qui lui est propre...

    En tout cas merci pour la réponse et si jamais quelqu'un voit autre chose, je suis toujours preneur !

    Bonne journée à tous,

    Slander

  4. #4
    Membre chevronné

    Inscrit en
    Avril 2003
    Messages
    284
    Détails du profil
    Informations forums :
    Inscription : Avril 2003
    Messages : 284
    Par défaut
    Doc Lazarus :
    http://lazarus-ccr.sourceforge.net/d.../tprocess.html
    puis
    property Input: TOutputPipeStream; [r]

    Stream connected to standard input of the process.
    je suis allé voir TOutputPipeStream
    http://lazarus-ccr.sourceforge.net/d...ipestream.html
    puis ses methodes
    http://lazarus-ccr.sourceforge.net/d...estream-3.html

    pour trouver Write

    THandleStream.Write
    Overrides standard write method.

    Declaration
    Source position: classesh.inc line 777

    public function THandleStream.Write(

    const Buffer;

    Count: LongInt

    ):LongInt; override;


    Description
    Write overrides the Write method of TStream. It uses the Handle property to write the Count bytes from Buffer.

    If no error occurs while writing, the number of bytes actually written will be returned.

    Errors
    If the operating system reports an error while writing to the handle, 0 is returned.
    tu devrais tester la valeur de sortie de ta fonction pour voir

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 14
    Par défaut
    J'ai lu la doc et j'ai remonté la hiérarchie des classes TInputPipeStream et TOutpuPipeStream (je l'ai mentionné dans mon 1er post) pour tomber sur ce que tu as écris dans ton dernier message. Voilà en fait ma procédure complète (je n'avais pas mis la partie affichage dans le debug vu que ce n'était qu'un affichage mais j'avais déjà le retour d'information voulu):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    procedure TMyProcess.WriteLine(const A_String: String);
    var
      I: Integer;
    begin
      if (Length(A_String) > 0) then
        begin
          // Les 2 lignes suivantes donnent le même résultat
          //I := Input.Write(A_String[1], Length(A_String));
          I := Input.Write(A_String, Length(A_String));
          AfficherDebug('TMyProcess.WriteLine: A_String = ' + A_String + ' (' + IntToStr(I) + ')');
        end;
    end;
    Lorsque j'utilise ma procédure le débug affiche:
    TMyProcess.WriteLine: A_String = quit (5)
    Le "5" indique bien que mes 5 caractères sont envoyés (quit + #10).

    Merci encore de l'intéret porté à mon problème , et bonne journée à toi.

    Slander

  6. #6
    Membre émérite
    Avatar de CapJack
    Homme Profil pro
    Prof, développeur amateur vaguement éclairé...
    Inscrit en
    Mars 2004
    Messages
    624
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Prof, développeur amateur vaguement éclairé...
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2004
    Messages : 624
    Par défaut
    C'est bête ce que je dis, mais ce n'est pas un #13 (EOL) qu'il faut envoyer en fin de ligne ?

  7. #7
    Membre chevronné

    Inscrit en
    Avril 2003
    Messages
    284
    Détails du profil
    Informations forums :
    Inscription : Avril 2003
    Messages : 284
    Par défaut
    Oui sous windows, mais pas sous linux

  8. #8
    Expert confirmé

    Inscrit en
    Août 2006
    Messages
    3 967
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 3 967
    Par défaut
    Bao,
    Citation Envoyé par CapJack Voir le message
    C'est bête ce que je dis, mais ce n'est pas un #13 (EOL) qu'il faut envoyer en fin de ligne ?
    #13, c'est CR (Carriage Return), pas EOL.

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 14
    Par défaut
    Petit test pour vous:

    Voilà un programme très simple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    program ProgrammeSimple;
     
    {$mode objfpc}{$H+}
     
    uses
      Classes, SysUtils;
     
    var
      Commande: String = '';
      Terminer: Boolean = False;
     
    begin
      WriteLn('Démarrage du programme...');
      WriteLn('Tappez "quit" pour quitter');
     
      repeat
        ReadLn(Commande);
     
        if (UpperCase(Commande) = 'QUIT') then
          Terminer := True
        else WriteLn('Tappez "quit" pour quitter');
      until Terminer;
     
      WriteLn('Programme terminé');
    end.
    2 problèmes se posent maintenant:
    1°) Impossible d'afficher les 2 lignes du programme dans un TProcess (en effet le TOutputPipeStream n'affiche les sorties que si le nombre de carctères esr multiple de 255 ~la taille d'un string )
    2°) Impossible de quitter proprement ce programme depuis un TProcess car il est impossible d'écrire vers le stdin...

    Je me demande donc a quoi peut bien servir la classe TProcess avec l'option poUsePipes ?

    Si quelqu'un arrive à faire fonctionner ce programme via un TProcess en arrivanr à récupérer le stdout et faire fonctionner le stdin, je suis prenneur...

    En attendant, je reste perplexe...

    Passez une bonne journée,

    Slander

Discussions similaires

  1. Réponses: 2
    Dernier message: 03/07/2009, 08h15
  2. [AJAX] input type=file avec php côté serveur
    Par redstain dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 04/01/2007, 15h43
  3. Problème de read/write
    Par mylooz dans le forum Entrée/Sortie
    Réponses: 7
    Dernier message: 25/03/2005, 19h15
  4. Problème de basckup Restore avec IBCONSOLE
    Par myseb dans le forum Outils
    Réponses: 10
    Dernier message: 04/11/2004, 14h48
  5. problème de capture son avec Directshow
    Par albator83 dans le forum DirectX
    Réponses: 2
    Dernier message: 06/11/2003, 17h18

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo