Programme en ligne de commande et programme en ligne de commande

Codes specifiques à Windows
NY152
Messages : 148
Inscription : dim. 14/mai/2006 20:41

Programme en ligne de commande et programme en ligne de commande

Message par NY152 »

Bonjour,

Je suis depuis un moment face à un bug dont je n'ai eu aucune réponse (j'ai d'ailleurs supprimé mon vieux post qui n'avait reçu aucune réponse pour refaire une demande, on peut rêver ^^)

J'ai écris plusieurs programmes fonctionnant en mode console. Dans ces programme, je fais appel de temps en temps à des programmes externes (FFMPEG par exemple mais le soucis se produit avec tous les programmes que j'ai pu tester) et au lieu d'avoir le retour dans le même invite de commande, une nouvelle fenêtre s'ouvre et bien sûr ces fenêtres se ferment à la fin de leurs exécutions et je perd le retour de ces programmes (pas simple quand le retour est indispensable à la suite du programme ...)

Ma question est simple : pourquoi les programmes externes ne s'affichent pas dans le même invite de commande que mon programme laçant ces derniers ? Il y a t-il un moyen de forcer la chose ?

Pour information, j'ai testé mes programmes avec la console graphique (avec le paramètre EnableGraphicalConsole) et aussi sans. J'ai testé divers options de compilation mais sans succès

Merci de m'aider à trouver la solution permettant d'exécuter mes programmes externe "proprement" ^^
.:NY152:.
Avatar de l’utilisateur
cage
Messages : 604
Inscription : ven. 16/oct./2015 18:22
Localisation : France
Contact :

Re: Programme en ligne de commande et programme en ligne de commande

Message par cage »

Bonjour NY152,

Dans Windows, pour capturer la sortie de certains programmes, j'utilise la commande clip

Voici un exemple un peu sioux qui devrait pouvoir t'aider.

Code : Tout sélectionner

EnableExplicit

OnErrorGoto(?ErrorHandler)

Global NewList SERVICES.s()

Global NewMap SERVICE_NAME.s() ; to dynamically populating all windows drivers and service SERVICE_NAME
Global NewMap DISPLAY_NAME.s() ; to dynamically populating all windows drivers and service DISPLAY_NAME

Procedure get_services(type$)
  Protected count=0 ,in, n, rc, entry$, file$
  Protected SERVICE_NAME.s, DISPLAY_NAME.s
  Protected string1$ = "SERVICE_NAME: "
  Protected string2$ = "DISPLAY_NAME: "
  Protected parameters$
  Select LCase(type$)
    Case "driver"
    Case "service"
    Default
      type$ = "service"
  EndSelect

  parameters$ = "/c sc.exe query type= "+type$+" state= all | findstr /i /c:"+string1$+" /c:"+string2$+" 2>&1|clip"
  
  rc = RunProgram("cmd.exe",parameters$,#Null$,#PB_Program_Wait|#PB_Program_Hide)
  
  entry$ = GetClipboardText() : ClearClipboard()
  
  count  = CountString(entry$, string1$)
  entry$ = RemoveString(entry$, string1$, #PB_String_NoCase)
  entry$ = RemoveString(entry$, string2$, #PB_String_NoCase)
  
  If count
    ClearList(SERVICES())
    ClearMap(DISPLAY_NAME())
    For n = 1 To 2 * count Step 2
      SERVICE_NAME = Trim(StringField(entry$, n+0, #CRLF$))
      DISPLAY_NAME = Trim(StringField(entry$, n+1, #CRLF$))
      DISPLAY_NAME(SERVICE_NAME) = DISPLAY_NAME
      AddElement(SERVICES())
      SERVICES() = SERVICE_NAME
    Next
  EndIf
EndProcedure ; get_services()

OpenConsole()
  PrintN(#Null$)
  
  get_services("service")

  ForEach SERVICES()
    PrintN(LSet(SERVICES(),32) + " | " + DISPLAY_NAME(SERVICES()))
  Next
  
  PrintN(#Null$)
  
  PrintN(LSet("-",120,"-"))
  
  get_services("driver")

  ForEach SERVICES()
    PrintN(LSet(SERVICES(),32) + " | " + DISPLAY_NAME(SERVICES()))
  Next
  
  PrintN(#Null$)
  
  PrintN(LSet("-",120,"-"))
  
  PrintN(#Null$)
  PrintN("Press return to exit")
  Input()
  
CloseConsole()

ErrorHandler:

End
cage
■ Win10 Pro 64-bit (Intel Celeron CPU N2920 @ 1.86GHz, 4,0GB RAM, Intel HD Graphics) & PB 6.12 LTS
■ Vivre et laisser vivre.
■ PureBasic pour le fun
■ Gérard sur le forum Anglais
■ Mes sites: http://pbcage.free.fr - http://yh.toolbox.free.fr
Avatar de l’utilisateur
TazNormand
Messages : 1297
Inscription : ven. 27/oct./2006 12:19
Localisation : Calvados (14)

Re: Programme en ligne de commande et programme en ligne de commande

Message par TazNormand »

Salut

à vérifier, mais je pense que cela vient du fait que ton exe lancé par Purebasic via RunProgram lance peut-être lui aussi un autre exe en mode console, ce qui fait que PureBasic ne peut pas intercepter cette autre console, puisque pour lui le retour vient du RunProgram et pas du fils de....

Je vais tâcher de faire un test avec 2 exe avec runprogram
Image
Image
Avatar de l’utilisateur
TazNormand
Messages : 1297
Inscription : ven. 27/oct./2006 12:19
Localisation : Calvados (14)

Re: Programme en ligne de commande et programme en ligne de commande

Message par TazNormand »

Bon j'ai testé avec 3 petit exe console : pere, fils et petitfils, et je confirme que le père récupère bien la sortie uniquement de fils et pas du petit fils :

Père :

Code : Tout sélectionner

; PERE

dosOut$=""
OpenConsole()
ConsoleTitle("Je suis ton père")
Print("Je suis ton père")
fils=RunProgram("fils.exe","","",#PB_Program_Ascii|#PB_Program_Open|#PB_Program_Read|#PB_Program_Error)
If fils
  While ProgramRunning(fils)
    If AvailableProgramOutput(fils)
      dosOut$+ReadProgramString(fils)+Chr(13)      
    EndIf    
Wend
dosOut$+Chr(13)+Chr(13)
dosOut$+"Exit Code : "+Str(ProgramExitCode(fils))
CloseProgram(fils)
EndIf
;Debug dosOut$
MessageRequester("Sortie du Fils", dosOut$)
CloseConsole()
Fils :

Code : Tout sélectionner

; FILS

dosOutf$=""
OpenConsole()
ConsoleTitle("Je suis ton fils")
Print("Je suis ton fils")
petitFils=RunProgram("petitFils.exe","","",#PB_Program_Ascii|#PB_Program_Open|#PB_Program_Read|#PB_Program_Error)
If petitFils
  While ProgramRunning(petitFils)
    If AvailableProgramOutput(petitFils)
      dosOutf$+ReadProgramString(petitFils)+Chr(13)      
    EndIf
Wend
dosOutf$+Chr(13)+Chr(13)
dosOutf$+"Exit Code : "+Str(ProgramExitCode(petitFils))
CloseProgram(petitFils)
EndIf
;Debug dosOutf$
MessageRequester("Sortie du petit Fils", dosOutf$)
CloseConsole()
Petit-Fils :

Code : Tout sélectionner

; PETIT-FILS

dosOut$=""
OpenConsole()
ConsoleTitle("Je suis ton petit-fils")
Print("Je suis ton petit-fils")
For i=1 To 20
  Print("Ligne "+Str(i)+Chr(13)+Chr(10))
  Delay(50)
Next i
CloseConsole()

Image
Image
Marc56
Messages : 2196
Inscription : sam. 08/févr./2014 15:19

Re: Programme en ligne de commande et programme en ligne de commande

Message par Marc56 »

C'est souvent compliqué de chainer des programmes en ligne de commande.
Le moyen simple et fiable consiste à lancer le premier programme avec #PB_Program_Wait, puis une fois terminé vérifier la présence, taille, ou date du fichier généré (dans le cas d'un filtre comme FFMPEG)
Pour faire plus finement, on peut aussi récupérer les informations du fichier de log, si l'outil peut en générer (ce qui est souvent le cas des programmes ligne de commande). Penser à verifier la date/heure du log pour ne pas relire le précédent lancement (erreur classique)
:wink:
NY152
Messages : 148
Inscription : dim. 14/mai/2006 20:41

Re: Programme en ligne de commande et programme en ligne de commande

Message par NY152 »

Désolé de ne répondre que maintenant, le temps me manque beaucoup en ce moment :/

Effectivement je lance FFMPEG avec RunProgram()

Je n'ai pas encore tester une autre méthode mais si j'ai le temps j'essayerai avec ShellExecute_() par exemple histoire de voire si cela change quelque chose.

@cage Pour ton exemple, l'idée me plait bien mais que ce passe t-il quand le programme appelé réclame une réponse (Dans le cas de FFMPEG si on tente de créer un média ayant un nom déjà existant, il demande à l'utilisateur de confirmer ou infirmer l'écrasement du fichier) ?

Je vous fais un retour dès que j'ai un peu de temps.

En tout cas, merci de votre aide :)
.:NY152:.
NY152
Messages : 148
Inscription : dim. 14/mai/2006 20:41

Re: Programme en ligne de commande et programme en ligne de commande

Message par NY152 »

J'ai testé vite fais avec ShellExecute_(), même soucis qu'avec RunProgram(), une seconde fenêtre s'ouvre

Ca va s'avérer plus complexe que prévu selon moi. La chose bizarre c'est qu'avant je n'ai jamais eu de soucis.
.:NY152:.
Avatar de l’utilisateur
cage
Messages : 604
Inscription : ven. 16/oct./2015 18:22
Localisation : France
Contact :

Re: Programme en ligne de commande et programme en ligne de commande

Message par cage »

Bonjour,

J'utilise les entrées/sorties du DOS qui fonctionnent toujours en mode console ou batch
L'entrée standard est normalement le clavier
La sortie standard est normalement l'écran
La sortie standard pour les erreurs est normalement l'écran
Les entrées/sorties peuvent êtres redirigées avec/vers NUL, 1, 2, >, <, |

Un exemple minimal avec la commande DEL

Code : Tout sélectionner

D:\>dir
 Le volume dans le lecteur D s’appelle Win10Pro
 Le numéro de série du volume est 3EF0-D9EE

 Répertoire de D:\

07/06/2022  00:12                24 non.txt
07/06/2022  00:30                24 oui.txt
16/05/2022  21:30    <DIR>          Public
30/10/2021  17:17         4 372 304 Vidéo01.mp4
06/11/2021  15:59         9 840 110 Vidéo02.mp4
07/06/2022  00:15                24 yes.txt
               5 fichier(s)       14 212 486 octets
               1 Rép(s)  720 022 294 528 octets libres

D:\>del /p *.mp4 < non.txt
D:\Vidéo01.mp4, Supprimer (O/N) ? n
D:\Vidéo02.mp4, Supprimer (O/N) ? n

D:\>del /p *.mp3 < non.txt
Impossible de trouver D:\*.mp3

D:\>
Le fichier non.txt contient plusieurs lignes contenant la lettre n
Le fichier oui.txt contient plusieurs lignes contenant la lettre o
Le fichier yes.txt contient plusieurs lignes contenant la lettre y

Code : Tout sélectionner

D:\>type non.txt
n
n
n
n
n
n
n
n

D:\>type oui.txt
o
o
o
o
o
o
o
o

D:\>type yes.txt
y
y
y
y
y
y
y
y

D:\>
Dans cet exemple, le fichier non.txt sert de réponse a la demande de confirmation de del /p *.mp4
Le fichiers ne sont donc pas effacés. Pour confirmer l'effacement

Code : Tout sélectionner

D:\>del /p *.mp4 < oui.txt
D:\Vidéo01.mp4, Supprimer (O/N) ? o
D:\Vidéo02.mp4, Supprimer (O/N) ? o

D:\>
cage
■ Win10 Pro 64-bit (Intel Celeron CPU N2920 @ 1.86GHz, 4,0GB RAM, Intel HD Graphics) & PB 6.12 LTS
■ Vivre et laisser vivre.
■ PureBasic pour le fun
■ Gérard sur le forum Anglais
■ Mes sites: http://pbcage.free.fr - http://yh.toolbox.free.fr
NY152
Messages : 148
Inscription : dim. 14/mai/2006 20:41

Re: Programme en ligne de commande et programme en ligne de commande

Message par NY152 »

Je comprends pas trop le fonctionnement là désolé ...
.:NY152:.
Avatar de l’utilisateur
cage
Messages : 604
Inscription : ven. 16/oct./2015 18:22
Localisation : France
Contact :

Re: Programme en ligne de commande et programme en ligne de commande

Message par cage »

Bonjour,
Un peu de lecture:
Les entrées/sorties en mode console
Batch Script - Input / Output
Un programme en ligne de commande est interactif lorsqu'il demande une intervention de l'utilisateur pour faire un choix.
Un programme peut par exemple demander de répondre soit (O)ui, soit (Y)es, soit (N)on, soit (N)o pour continuer ce qu'il doit faire.
Ces réponses peuvent êtres inscrites a l'avance dans un fichier qui servira a automatiser le processus.
@cage Pour ton exemple, l'idée me plait bien mais que ce passe t-il quand le programme appelé réclame une réponse (Dans le cas de FFMPEG si on tente de créer un média ayant un nom déjà existant, il demande à l'utilisateur de confirmer ou infirmer l'écrasement du fichier) ?
Pour ce cas que tu évoques, il faut savoir a l'avance la réponse que tu souhaites faire et l'inscrire dans un fichier qui sera lu en en entrée de FFMPEG
cage
■ Win10 Pro 64-bit (Intel Celeron CPU N2920 @ 1.86GHz, 4,0GB RAM, Intel HD Graphics) & PB 6.12 LTS
■ Vivre et laisser vivre.
■ PureBasic pour le fun
■ Gérard sur le forum Anglais
■ Mes sites: http://pbcage.free.fr - http://yh.toolbox.free.fr
NY152
Messages : 148
Inscription : dim. 14/mai/2006 20:41

Re: Programme en ligne de commande et programme en ligne de commande

Message par NY152 »

OK je comprends mieux ...

Alors si pour le cas de l'écrasement du fichier un oui ou non peut suffire (encore faut-il savoir ce que l'on veut faire au moment M)

Pour le cas d'une entrée comme un taux d'échantillonnage ou autre cette solution devient plus un problème qu'autre chose, il faudrait prévoir toutes solutions, autant réinventer la roue ou faire un bête VBS ou batch si Purebasic est incapable de faire ce qu'il faisait très bien avant ...
.:NY152:.
Avatar de l’utilisateur
cage
Messages : 604
Inscription : ven. 16/oct./2015 18:22
Localisation : France
Contact :

Re: Programme en ligne de commande et programme en ligne de commande

Message par cage »

Au final, j'ai répondu d'une manière générale mais sans savoir exactement ce que tu cherches a faire.
La solution que je te propose fonctionne très bien pour moi dans certains cas, après c'est sur, tous les cas ne sont pas forcements prévisibles et demandent de s'y pencher plus avant.
Et c'est ce qui me plait avec PB qui peut inclure des procédures en mode console (cmd.exe), en vbs, en php, ou tout autre langage.
cage
■ Win10 Pro 64-bit (Intel Celeron CPU N2920 @ 1.86GHz, 4,0GB RAM, Intel HD Graphics) & PB 6.12 LTS
■ Vivre et laisser vivre.
■ PureBasic pour le fun
■ Gérard sur le forum Anglais
■ Mes sites: http://pbcage.free.fr - http://yh.toolbox.free.fr
Marc56
Messages : 2196
Inscription : sam. 08/févr./2014 15:19

Re: Programme en ligne de commande et programme en ligne de commande

Message par Marc56 »

(Dans le cas de FFMPEG si on tente de créer un média ayant un nom déjà existant, il demande à l'utilisateur de confirmer ou infirmer l'écrasement du fichier) ?
Pour ffmpeg, il y a une option pour confirmer ou non la réécriture si le fichier existe déjà
https://ffmpeg.org/ffmpeg.html#Main-options

Code : Tout sélectionner

5.4 Main options
...
-y (global)
Overwrite output files without asking.

-n (global)
Do not overwrite output files, and exit immediately if a specified output file already exists.
...
- Pratiquement tous les programmes ligne de commande ont une option /y ou -y pour répondre "yes" par défaut.
- Certains programme DOS/Windows sont conçus (depuis longtemps) pour écraser par défaut s'ils sont lancés dans un batch même sans paramètre de confirmation.
NY152
Messages : 148
Inscription : dim. 14/mai/2006 20:41

Re: Programme en ligne de commande et programme en ligne de commande

Message par NY152 »

@Marc56 : L'histoire du fichier déjà existant n'est qu'un exemple parmi tant d'autre, cela pourrait être un des paramètres voulu lors de l'exécution.

Et puis cela ne règle pas le soucis principal à savoir que quand on appelle un programme externe, il s'exécute dans une fenêtre différente et non dans la même. Quel intérêt me dira t-on : J'ai un outil qui analyse une situation et qui en renvoi les infos et selon le retour, l'utilisateur peut décider quoi faire. Dans la situation actuelle, l'outil est bien appelé mais disparait aussi vite. Et je ne parle pas d'autres nombreux cas.
.:NY152:.
Avatar de l’utilisateur
cage
Messages : 604
Inscription : ven. 16/oct./2015 18:22
Localisation : France
Contact :

Re: Programme en ligne de commande et programme en ligne de commande

Message par cage »

Si tu avais un exemple que l'on puisse reproduire, ce serait cool.
cage
■ Win10 Pro 64-bit (Intel Celeron CPU N2920 @ 1.86GHz, 4,0GB RAM, Intel HD Graphics) & PB 6.12 LTS
■ Vivre et laisser vivre.
■ PureBasic pour le fun
■ Gérard sur le forum Anglais
■ Mes sites: http://pbcage.free.fr - http://yh.toolbox.free.fr
Répondre