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

Pascal Discussion :

Echange de texte avec une application console


Sujet :

Pascal

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2011
    Messages
    4 167
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 4 167
    Billets dans le blog
    9
    Par défaut Echange de texte avec une application console
    Bonjour !

    Je voudrais faire un programme qui utilise FBeauty. C'est une application console. Vous l'ouvrez, vous tapez print puis Entrée, la console affiche PRINT.

    Le programme est donné avec un script qui permet d'automatiser le processus et de filtrer un fichier source d'un coup.

    Code batch : Sélectionner tout - Visualiser dans une fenêtre à part
    FBeauty < Entree.txt > Sortie.bas

    Comment est-ce que je peux faire ça en Pascal, je veux dire envoyer une chaîne à l'application (au lieu de l'entrer au clavier) et recevoir la chaîne modifiée (au lieu de la lire à l'écran) ?
    Fichiers attachés Fichiers attachés

  2. #2
    Membre éclairé
    Avatar de EpiTouille
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2009
    Messages
    372
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2009
    Messages : 372
    Par défaut
    Pour interargir avec ce programme, tu peux utilisé une unité de free-pascal

    voila le lien avec des exemples, il est montré comment lire la sortie du programme et lancer un programme externe, j'espere que c'est ça que tu cherches

    http://wiki.freepascal.org/Executing...al_Programs/fr

  3. #3
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2011
    Messages
    4 167
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 4 167
    Billets dans le blog
    9
    Par défaut
    Merci pour ta réponse, EpiTouille. Oui, c'est bien ça. J'ai commencé à étudier les exemples : je pense ne pas être loin de la solution.

    Dans la FAQ Delphi, il y a un exemple qui correspond exactement à mon problème mais il n'est pas dit comment faire en Pascal ce que fait le batch.

    J'ai déjà trouvé la solution en Basic.

    Code vb : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    sub generateFile(src as string, dst as string, flt as string, opt as string)
      dim s as string
      open dst for output as #1
      open pipe flt & " " & opt & " < " & src for input as #2
      do until eof(2)
        line input #2, s
        print #1, s
      loop
      close #2
      close #1
    end sub

    Code vb : Sélectionner tout - Visualiser dans une fenêtre à part
    generateFile("C:\ancien.bas", "C:\nouveau.bas", "C:\FBeauty.exe", "-c")

    Il doit bien y avoir un équivalent de cet open pipe en Pascal ?

  4. #4
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2011
    Messages
    4 167
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 4 167
    Billets dans le blog
    9
    Par défaut
    Citation Envoyé par Roland Chastain Voir le message
    Dans la FAQ Delphi, il y a un exemple qui correspond exactement à mon problème mais il n'est pas dit comment faire en Pascal ce que fait le batch.
    Je n'étais pas allé assez loin : en fait il y a plusieurs entrées sur les redirections. Et il y a une archive contenant entre autres un exemple d'utilisation de CreateProcess qui est exactement ce dont j'avais besoin.

    C'est beaucoup plus long que mon bout de code en Basic, mais les possibilités de contrôle sont tout autres.

  5. #5
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2011
    Messages
    4 167
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 4 167
    Billets dans le blog
    9
    Par défaut
    Pour revenir à l'unité Process de FreePascal, je viens de m'apercevoir que la version anglaise de la page mentionnée au début de la discussion est plus récente et plus complète. Apparemment la solution à mon problème y est exposée de façon détaillée.

  6. #6
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2011
    Messages
    4 167
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 4 167
    Billets dans le blog
    9
    Par défaut
    Voici le code basé sur la fonction CreateProcess de l'unité Windows.

    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
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
     
    program CreateProcess2;
     
    {$IFDEF VPASCAL}
    {&PMTYPE VIO}
    {&USE32+}
    {$ELSE}
    {$APPTYPE CONSOLE}
    {$IFDEF FPC}{$MODE DELPHI}{$ENDIF}
    {$ENDIF}
     
    uses
      Windows, Messages, SysUtils;
     
    // http://laurent-dardenne.developpez.com/Sources/RedirectionConsole.zip
     
    function CreateDOSProcessRedirected(const aCL, aIF, aOF: string): boolean;
    // CL=CommandLine, IF=InputFile, OF=OutputFile
    const
      a = GENERIC_READ or GENERIC_WRITE;
      b = FILE_SHARE_READ or FILE_SHARE_WRITE;
      c = OPEN_ALWAYS;
      d = CREATE_ALWAYS;
      e = FILE_ATTRIBUTE_NORMAL or FILE_FLAG_WRITE_THROUGH;
      f = INVALID_HANDLE_VALUE;
      g = STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
      h = HIGH_PRIORITY_CLASS;
      i = SW_HIDE;
      j = INFINITE;
    var
      SI  : TStartupInfo;
      PI  : TProcessInformation;
      SA  : TSecurityAttributes;
      hAP, hAT, hIF, hOF : THandle; // AP=ApplicationProcess, AT=ApplicationThread
      pCL, pIF, pOF : array[0..MAX_PATH] of char;
    begin
      if not FileExists(aIF) then
      begin
        Result := False;
        Exit;
      end else
        Result := True;
    ////////////////////////////////////////////////////////////////////////////////
      StrPCopy(pCL, aCL);
      StrPCopy(pIF, aIF);
      StrPCopy(pOF, aOF);
    ////////////////////////////////////////////////////////////////////////////////
      FillChar(SA, SizeOf(SA), #0);
      with SA do begin
        nLength := SizeOf(SA);
        lpSecurityDescriptor := nil;
        bInheritHandle := True;
      end;
    ////////////////////////////////////////////////////////////////////////////////
      hIF := CreateFile(pIF, a, b, @SA, c, e, 0);
      hOF := CreateFile(pOF, a, b, @SA, d, e, 0);
    ////////////////////////////////////////////////////////////////////////////////
      Result := Result and (hIF <> f) and (hOF <> f);
    ////////////////////////////////////////////////////////////////////////////////
      FillChar(SI, SizeOf(SI), #0);
      with SI do begin
        cb := SizeOf(SI);
        dwFlags := g;
        wShowWindow := i;
        hStdOutput := hOF;
        hStdInput := hIF;
      end;
    ////////////////////////////////////////////////////////////////////////////////
      Result := Result and
        CreateProcess(nil, pCL, nil, nil, True, h, nil, nil, SI, PI);
    ////////////////////////////////////////////////////////////////////////////////
      if Result then
      begin
        WaitforSingleObject(PI.hProcess, j);
        hAP := PI.hProcess;
        hAT := PI.hThread;
      end;
    ////////////////////////////////////////////////////////////////////////////////
      if hOF <> f then CloseHandle(hOF);
      if hIF <> f then CloseHandle(hIF);
      if hAT <> f then CloseHandle(hAT);
      if hAP <> f then CloseHandle(hAP);
    end;
     
    const
      s = 'Fonction termin'#130'e avec succ'#138's.';
     
    begin
    { Le fichier minuscule.txt sera traité par l'application Upper et le résultat
      enregistré dans majuscule.txt. }
      if CreateDOSProcessRedirected('Upper ','minuscule.txt', 'majuscule.txt') then
        WriteLn(s);
     
    { Le fichier ancien.bas sera traité par l'application FBeauty et le résultat
      enregistré dans nouveau.bas. }
      if CreateDOSProcessRedirected('FBeauty ','ancien.bas', 'nouveau.bas') then
        WriteLn(s);
     
      WriteLn('Appuyez sur la touche Entr'#130'e');
      ReadLn;
    end.
    Maintenant je vais m'attaquer à l'unité Process.
    Fichiers attachés Fichiers attachés

  7. #7
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2011
    Messages
    4 167
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 4 167
    Billets dans le blog
    9
    Par défaut
    Bonjour !

    Je reviens une dernière fois peut-être à cette discussion. En modifiant des exemples que j'avais trouvés, j'ai réussi à faire ce que je voulais, mais j'ai l'impression de ne toujours pas maîtriser le sujet.
    Voici le problème sur lequel je travaille en ce moment. J'ai fait une application console (un moteur de "Puissance 4") qui s'utilise de la façon suivante : on l'exécute avec un paramètre qui est une chaîne contenant les coups déjà joués, par exemple "433", et le moteur renvoie son coup, par exemple "4". J'ai besoin de lire ce coup à partir de mon deuxième programme, qui est une interface graphique.
    Sur la page indiquée par Epitouille, le deuxième exemple fait le travail, mais en passant par une liste de chaînes, ce qui serait un peu lourd puisque dans mon cas il n'y a qu'une seule ligne (et même un seul caractère) à lire.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
       // Maintenant on lit dans la TStringList la sortie du programme.
       AStringList.LoadFromStream(AProcess.Output);
    Y aurait-il moyen de faire la même chose sans la liste de chaînes ?

    D'autre part, pardon de vous embêter encore avec mon Basic, mais je cherche toujours à savoir s'il n'y a pas en Pascal standard un équivalent de ce bout de code :

    Code vb : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    OPEN PIPE "executable.exe 433" FOR INPUT AS #1
    DIM AS STRING ln
    LINE INPUT #1, ln
    CLOSE #1

  8. #8
    Membre éclairé
    Avatar de EpiTouille
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2009
    Messages
    372
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2009
    Messages : 372
    Par défaut
    Bonjour,
    Il n'y a pas de fonction standard faisant la même chose que ton code Basic.

    Si tu veux, tu peux recréer tes fonctions, mais pour ça du dois le faire à la main avec les équivalents dup/dup2/pipe... Ca demande aussi de bien comprendre le fonctionnement des pipes.

  9. #9
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2011
    Messages
    4 167
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 4 167
    Billets dans le blog
    9
    Par défaut
    Citation Envoyé par Roland Chastain Voir le message
    Y aurait-il moyen de faire la même chose sans la liste de chaînes ?
    J'ai trouvé la solution . Il y a même deux solutions différentes, la seconde utilisant la fonction RunCommand, que je ne connaissais pas et qui fait en une ligne ce dont j'avais besoin.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    program Execute;
     
    uses 
      Process;
     
    var
      s: ansiString;
     
    begin
      if RunCommand('Moteur.exe', ['433'], s) then
        WriteLn(s);
      ReadLn; 
    end.
    J'ai repris un vieux Puissance 4 en mode texte pour faire une petite démo rapide. J'ai remplacé le contenu de la fonction MeilleurCoup() par le code ci-dessus (avec les modifications qu'il fallait, bien entendu). Le moteur, que je n'avais pas testé, semble jouer très mal, ou alors j'ai fait une erreur dans le montage, je ne sais pas, mais peu importe : ça fonctionne !

    [edit]

    Voilà, avec un dernier réglage du moteur, ça va encore mieux.
    Fichiers attachés Fichiers attachés

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Dialoguer avec une application console
    Par fab56 dans le forum Langage
    Réponses: 2
    Dernier message: 30/01/2011, 15h55
  2. Réponses: 9
    Dernier message: 17/11/2008, 17h18
  3. Réponses: 8
    Dernier message: 20/06/2007, 13h19
  4. Texte d'une application console
    Par Mickael Provost dans le forum Windows
    Réponses: 4
    Dernier message: 30/08/2005, 23h18
  5. Réponses: 4
    Dernier message: 25/04/2005, 19h36

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