Page 1 sur 1
[R] Connaître le Return d'un executable
Posté : mer. 08 juil. 2015 12:52
par caropost
Bonjour,
On m'a demandé de rédiger 2 scripts avec Script1 qui fait appel à des fonctions dans Script2 qui n'ont pour seul but que de renvoyer une variable à Script1.
► Afficher le texteScript1.au3
Code : Tout sélectionner
For $i = 1 To 5
MyFunction($i, $j, $k) ; j et k sont définis plus haut dans mon code
Run("notepad.exe")
WinWaitActive("Untitled - Notepad")
Send("NOM DE LA PERSONNE : " & nom() & "{ENTER}")
Send("PRENOM DE LA PERSONNE : " & prenom() & "{ENTER}")
Send("AGE DE LA PERSONNE : " & age() & "{ENTER}")
Send("^s")
Send(nom() & "_personne{ENTER}")
WinWaitActive(nom() & "_personne.txt - Notepad")
WinClose(nom() & "_personne.txt - Notepad")
► Afficher le texteScript2.au3
Code : Tout sélectionner
Local $nom = "Dupond"
Local $prenom = "Charles"
Local $age = "26 ans"
Func nom()
Return $nom
EndFunc
Func prenom()
Return $prenom
EndFunc
Func age()
Return $age
EndFunc
Func MyFunction($Arg1, $Arg2, $Arg3)
MsgBox(0, "My title", 'Je lance MyFunction avec $Arg1 = ' & $Arg1 & ' et $Arg2 = ' & $Arg2 & ' et $Arg3 = ' & $Arg3)
EndFunc
Je ne vous ai pas tout mis mais le reste n'est pas important pour mon problème.
Ceci fonctionne mais là où ça se complique c'est lorsque je souhaite compiler les 2 scripts (demande forte)... Pour faire ce que je souhaite, j'ai dû changer les "Return $nom" en "Send($nom)" et on m'a demandé de voir si je ne pouvais pas garder les Return de mes fonctions... Le truc est que je ne vois pas trop comment faire et si c'est possible...
De plus, pour pouvoir récupérer le nom (comme j'enregistre le fichier avec cette variable et que j'ai besoin de la connaître pour attendre que le processus soit prêt), je copie la variable dans un presse-papier à l'aide de ClipGet et ClipPut mais il doit y avoir plus "propre" comme façon de faire...
Merci par avance pour votre aide

Re: [..] Connaître le Return d'un executable
Posté : mer. 08 juil. 2015 14:14
par jchd
Voir l'aide sur Exit.
Re: [..] Connaître le Return d'un executable
Posté : mer. 08 juil. 2015 14:54
par orax
D'après ce que j'ai compris elle cherche plutôt à obtenir une chaîne de caractères (pas seulement un code numérique).
Les fonctions Std* (StdoutRead...) pourraient convenir pour cette tâche, mais il y a d'autres façons de faire (voir communication inter-processus, IPC).
Est-ce que Script2.exe sera toujours exécuté sur le même PC que Script1 ? Car il serait possible d'interroger Script2 à distance (via le réseau) si cela fait partie des contraintes.
Re: [..] Connaître le Return d'un executable
Posté : mer. 08 juil. 2015 18:00
par jchd
Ah, si caro veut passer autre chose qu'un code de sortie d'exécutable forcément numérique [ce qui est pourtant le titre de ce fil] alors, en effet, le plus robuste serait d'utiliser un IPC, genre mailslot.
Re: [..] Connaître le Return d'un executable
Posté : jeu. 09 juil. 2015 08:51
par caropost
Mon titre est peut-être mal choisi et je me suis peut-être mal exprimé, je suis désolée
Mais l'idée est que j'ai $nom qui est défini dans Script2 et que je le retourne à Script1 à l'aide d'une petite fonction qui ne contient que "return $nom". De cette façon, je peux, avant compilation, attendre que "Dupond_presonne.txt" soit actif et de fermer ce fichier sans avoir une variable dans Script1 qui récupère ce nom. Ce n'est donc pas un numéro que j'attends.
Mon return fonctionne très bien avant compilation mais plus après compilation...
Et donc je cherche à savoir si je peux garder ma fonction avec un Return ou si je dois complètement la changer. J'ai transformé mon "return" en "send" mais ça ne plait qu'à moitié...
Je regarde les IPC mais de ce que j'en ai lu pour l'instant, ainsi que les quelques lignes de code, j'ai sorti les rames...

Re: [..] Connaître le Return d'un executable
Posté : jeu. 09 juil. 2015 10:12
par jchd
Ce que je n'ai pas trop compris c'est pourquoi tu tiens à avoir deux scripts. Tu dis que l'un est essentiellement stable et figé, tandis que l'autre sera modifié régulièrement. Si c'est pour y loger des informations variables dans le temps, type infos de connexion (par exemple), pourquoi ne pas les stocker dans un conteneur commun à accès limité par droit ou chiffrement ?
En bref, à quoi sert script2 et pourquoi le recompiler sans cesse ?
Re: [..] Connaître le Return d'un executable
Posté : jeu. 09 juil. 2015 11:46
par caropost
Pour des raisons de confidentialité je ne vais pas trop pouvoir répondre à tes questions...
C'est une contrainte forte de mon tuteur d'avoir, non seulement 2 scripts mais en plus de les compiler tous les 2. Si ça ne tenais qu'à moi, j'aurais tout mis dans le même script...
Script1 est suffisamment générique pour pour ne pas y toucher tandis que Script2 s'adapte en fonction de ce qu'on veut faire. Les fonctions contenant un return ne sont pas censé changer, juste le contenu des variables. Le nom MyFunction n'est pas censé bouger mais son contenu change. Script2 ne peut pas fonctionner sans Script1.
Dans mes différents posts, tu as peut-être remarqué que je vous donnais des exemples de code avec des fleurs. Bah image que aujourd'hui MyFunction sert à répertorier des fleurs mais demain on devra pouvoir adapter son contenu pour qu'il répertorie des arbres, des voitures ou encore des téléphones sans avoir à modifier Script1...
Mon tuteur m'a demandé de compilé les 2 scripts pour qu'il n'y ai pas de mauvaise manipulation par erreur (au pire le fichier est supprimé) et pour pouvoir les donner à quelqu'un qui n'a pas AutoIt d'installé sur un PC.
A quoi penses-tu pour le conteneur ?
Re: [..] Connaître le Return d'un executable
Posté : jeu. 09 juil. 2015 16:17
par Tlem
Bonjour.
Si le script 2 n'a pas besoin d'interface graphique (d'après ce que j'ai compris, il est là uniquement pour retourner des valeurs) alors il peut être intéressent de le compiler en CUI, comme ça les valeurs seront retournées dans la console. ^^
Il suffira à script 1 de lire le retour console (StdoutRead...) pour avoir la/les valeurs de retour.
Re: [..] Connaître le Return d'un executable
Posté : jeu. 09 juil. 2015 17:05
par caropost
Tlem a écrit :Bonjour.
Si le script 2 n'a pas besoin d'interface graphique (d'après ce que j'ai compris, il est là uniquement pour retourner des valeurs) alors il peut être intéressent de le compiler en CUI, comme ça les valeurs seront retournées dans la console. ^^
Il suffira à script 1 de lire le retour console (StdoutRead...) pour avoir la/les valeurs de retour.
Il ne fait pas que ça mais en partie. La plus grosse partie se trouve dans MyFunction qui fonctionne bien (mis à part mon problème d'écriture des logs dans un fichier texte) mais ne retourne rien.
Comment fait-on pour compiler en CUI ? Je n'ai que "Compiler" lorsque je fais un clique droit pour compiler...
Re: [..] Connaître le Return d'un executable
Posté : jeu. 09 juil. 2015 18:36
par jguinch
@Thierry : sauf erreur de ma part, il n'y a pas forcément besoin de compiler en CUI pour utiliser ConsoleWrite
Caro a écrit :2 scripts avec Script1 qui fait appel à des fonctions dans Script2
Caro, je ne comprends pas trop : comment ton script1 peut-il appeler des fonctions dans le script2 ?
Re: [..] Connaître le Return d'un executable
Posté : jeu. 09 juil. 2015 19:20
par mikell
$CmdLine ne marcherait pas ici ?
► Afficher le textescript1.au3
Code : Tout sélectionner
Local $nom = "Dupond"
Local $prenom = "Charles"
Local $age = "26 ans"
Local $string = '"' & $nom & "," & $prenom& "," & $age & '"'
ShellExecute(@ScriptDir & '\Script2.au3', $string )
► Afficher le textescript2
Re: [..] Connaître le Return d'un executable
Posté : ven. 10 juil. 2015 14:24
par caropost
jguinch a écrit :@Thierry : sauf erreur de ma part, il n'y a pas forcément besoin de compiler en CUI pour utiliser ConsoleWrite
Caro a écrit :2 scripts avec Script1 qui fait appel à des fonctions dans Script2
Caro, je ne comprends pas trop : comment ton script1 peut-il appeler des fonctions dans le script2 ?
Avec un ShellExecuteWait...
Afin que vous compreniez mieux ce que j'essaie de faire, je ne vous donne pas tout le code mais en partie. Comme ça, ça sera un peu plus concret...
► Afficher le texteScript1.exe
#include <PlinkWrapper.au3>
Local $username = "username"
Local $password = "password"
Local $repertoire = @DesktopDir
Local $nombre = 5
Local $com
; Un tableau est rempli
; Connexion sur un switch
$_plinkhandle1=_Start_plink($repertoire & "\plink.exe","COM1")
$hlog = _Init_plink_log($repertoire & "\Log\Log_Sw.log")
_Say(@CR, $_plinkhandle1)
_Expect("login :", $_plinkhandle1)
_SayPlus($username, $_plinkhandle1)
_Expect("password", $_plinkhandle1)
_SayPlus($password, $_plinkhandle1)
_Expect("Welcome", $_plinkhandle1)
For $i = 1 To $nombre
; Manipulation sur le switch
$com = "COM" & $i+1
; Appel à la fonction MyFunction de Script2. Je dois le changer en ShellExecute + "while flag = -1 récupérer la valeur dans le STDIN et passer le flag à 1"
ShellExecuteWait('Script2.exe', $i & ' ' & $com & ' ' & '"' & $repertoire & '"', $repertoire)
; Si quelque chose s'est mal passe, tout quitter. Ca aussi ça ne lui plait pas trop...
$exit = ClipGet()
If $exit = True Then Exit
; Récupération de la variable $nom qui est définie dans Scipt2. Ca non plus...
RunWait("Script2.exe", $repertoire)
Sleep(500)
$nom = ClipGet()
; Enregistrement de la bonne exécution des choses
Run("notepad.exe")
WinWaitActive("Untitled - Notepad")
Send("NOM DU SCRIPT : ")
Sleep(500)
ShellExecuteWait('Script2.exe', 'nom', $repertoire)
Sleep(500)
Send("VERSION DU SCRIPT : ")
Sleep(500)
ShellExecuteWait('Script2.exe', 'version', $repertoire)
Sleep(500)
Send("{ENTER}")
; [...]
Send("^s")
Send($repertoire & "\Save\" & $nom & "." & $tableau[$i-1][2] & "{ENTER}")
WinWaitActive($nom & "." & $tableau[$i-1][2] & " - Notepad")
Sleep(500)
WinClose($nom & "." & $tableau[$i-1][2] & " - Notepad")
Sleep(500)
Next
► Afficher le texteScript2.exe
Code : Tout sélectionner
#include <PlinkWrapper.au3>
Local $nom = "Script2"
Local $version = "V1"
Func nom()
Send($nom & @CR) ; bof
; Return $nom ; Le return ne fonctionne plus avec l'exe
EndFunc
Func version()
Send($version & @CR) ; bof
; Return $version ; Le return ne fonctionne plus avec l'exe
EndFunc
ClipPut($nom) ; il y a plus propre mais je n'ai pas encore vu comment
Local $i, $Arg[4] = ['', '','', '']
If $CmdLine[0] = 0 Then
MsgBox(0, @ScriptName, 'Aucun paramètre passé à Script2.exe')
Else
; On récupères les 4 premiers paramètres (voir le 1er s'il n'y en a qu'un)
For $i = 1 to $CmdLine[0]
If $i > 4 Then ExitLoop
$Arg[$i -1] = $CmdLine[$i]
Next
; on appelle la fonction
If($Arg[0] = "nom") Then
nom()
ElseIf($Arg[0] = "version") Then
version()
Else
MyFunction($Arg[0], $Arg[1], $Arg[2], $Arg[3])
EndIf
EndIf
Func MyFunction($i, $com, $repertoire)
$_plinkhandle2=_Start_plink($repertoire & "\plink.exe", $com)
$hlog2 = _Init_plink_log($repertoire & "\Log" & $i & ".log")
_Say(@CR, $_plinkhandle2)
_Expect("login :", $_plinkhandle2)
_SayPlus($user, $_plinkhandle2)
_Expect("password", $_plinkhandle2)
_SayPlus($password, $_plinkhandle2)
_Expect("Welcome", $_plinkhandle2)
; [...]
EndFunc
► Afficher le textePlinkWrapper.au3
Code : Tout sélectionner
func _Start_plink($_plink_loc,$_plinkserver)
if $_plink_loc = "" then
MsgBox(0, "Error", "Unable to open plink.exe",10)
return false
Exit
endif
if $_plinkserver = "" then
MsgBox(0, "Error", "Unable to open server",10)
Exit
return false
endif
Local $_plinkhandle = Run($_plink_loc & " -serial " & $_plinkserver,"",@SW_MAXIMIZE, $STDIN_CHILD + $STDOUT_CHILD) ; $STDIN_CHILD + $STDOUT_CHILD + $STDERR_CHILD)
return $_plinkhandle
endFunc
func _Init_plink_log($_plink_logfile)
$_plink_logfile_handle = FileOpen($_plink_logfile, 2)
; Check if file opened for writing OK
If $_plink_logfile_handle = -1 Then
MsgBox(0, "Error", "Unable to open file.")
Exit
EndIf
return true
endfunc
func _Expect($match_text, $_plinkhandle)
local $text
local $sBuffertext
local $count = 0
local $found
local $exit = FALSE
local $iBegin = TimerInit()
While 1
if TimerDiff($iBegin) > $_plink_timeout then return false
if $count = 50 Then
MsgBox(0, "timeout", '"' & $match_text & '"' & " non trouvé")
$exit = TRUE
return $exit
Exit
EndIf
$text = StdoutRead($_plinkhandle)
$sBuffertext = $sBuffertext & $text
if $_plink_logging Then
filewriteline($_plink_logfile_handle,"**********************NEW SECTION************************")
FileWriteLine($_plink_logfile_handle, "expect : " & $match_text)
FileWriteLine($_plink_logfile_handle, "read : " & $text)
; filewriteline($_plink_logfile_handle,"**********************END SECTION************************")
endif
$count = $count+1
$found = StringRegExp($text,$match_text)
If $found = 1 Then
; If $_plink_display_messages Then MsgBox(4096, $match_text, $text, $_plink_display_message_time)
ExitLoop
Endif
sleep(1000)
Wend
return $exit
return $sBuffertext
EndFunc
func _Say($output, $_plinkhandle)
StdinWrite($_plinkhandle, $output)
endfunc
func _SayPlus($output, $_plinkhandle)
StdinWrite($_plinkhandle, $output & @CR)
endfunc
Je me doute bien que des fois je dois me compliquer la vie pour rien mais ça ressemble beaucoup à ce qui m'a été demandé...
Le but de ce post était de savoir comment Script1 peut, plus proprement, récupérer les valeur de $nom, $version sachant que le souhait de mon tuteur était d'avoir des fonctions qui ne contiennent que le return...
J'ai essayé :
Script1.exe
Code : Tout sélectionner
Send("NOM DU SCRIPT : ")
Sleep(500)
StringReplace($CmdLine[1], "Script2", @crlf)
Script2.exe
mais ça me fait n'importe quoi...
Re: [..] Connaître le Return d'un executable
Posté : ven. 10 juil. 2015 16:13
par orax
► Afficher le texteScript2.exe
Code : Tout sélectionner
#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Change2CUI=y ; pas obligatoire mais est visiblement nécessaire pour tester le script en ligne de commande
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
;~ #include <PlinkWrapper.au3>
Local $nom = "Script2"
Local $version = "V1"
Func nom()
ConsoleWrite($nom)
EndFunc ;==>nom
Func version()
ConsoleWrite($version)
EndFunc ;==>version
Local $i, $Arg[4] = ['', '', '', '']
If $CmdLine[0] = 0 Then
MsgBox(0, @ScriptName, 'Aucun paramètre passé à Script2.exe')
Else
; On récupères les 4 premiers paramètres (voir le 1er s'il n'y en a qu'un)
For $i = 1 To $CmdLine[0]
If $i > 4 Then ExitLoop
$Arg[$i - 1] = $CmdLine[$i]
Next
; on appelle la fonction
If ($Arg[0] = "nom") Then
nom()
ElseIf ($Arg[0] = "version") Then
version()
Else
;~ MyFunction($Arg[0], $Arg[1], $Arg[2], $Arg[3])
EndIf
EndIf
Je peux ensuite tester ce script depuis l'invite de commandes (cmd.exe) mais la ligne
#AutoIt3Wrapper_Change2CUI=y (pour compiler en CUI) semble être nécessaire dans ce cas, sinon il n'y a rien qui s'affiche dans cmd.exe.
Code : Tout sélectionner
C:\autoit>Script2.exe version
V1
C:\autoit>Script2.exe nom
Script2
► Afficher le texteScript1.exe
Code : Tout sélectionner
#include <Constants.au3>
Local $pid = Run("Script2.exe nom", @ScriptDir, @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD)
If @error Then Exit -1
ProcessWaitClose($pid)
Local $nom = StdoutRead($pid)
ConsoleWrite($nom & @CRLF)
Re: [..] Connaître le Return d'un executable
Posté : ven. 10 juil. 2015 21:38
par Tlem
jguinch a écrit :@Thierry : sauf erreur de ma part, il n'y a pas forcément besoin de compiler en CUI pour utiliser ConsoleWrite

Ben si tu veux exploiter les retours en mode console, il n'y a pas le choix ...
Maintenant, il est clair que la lecture du flux directement depuis un exe compilé de manière classique est une solution, mais pas facile de tester les fonctions en live une fois compilé (ou alors il faut rajouter un mode Debug qui affichera les résultats dans une boite de dialogue.
Ce sera toujours mieux que les Send utilisés par caropost.

Re: [..] Connaître le Return d'un executable
Posté : mer. 15 juil. 2015 14:17
par caropost
Merci pour vos réponses
Effectivement Orax, ça fonctionne pas trop mal

J'ai tout de même un petit soucis...
J'ai un PC avec une version de XP assez ancienne et je pense qu'à cause de cela, je n'ai pas "Compile with options" lorsque je fais un clique droit sur le script. Je compilais normalement Script2 avec les 3 premières lignes qu'Orax a ajouté (#Region etc) mais en testant en ligne de commande ça ne fonctionnait pas (je n'avais pas le nom du script qui s'affichait dans cmd.exe). En cherchant un peu sur internet, j'ai vu qu'on pouvait compiler avec des options et en trouvant un PC avec un XP un peu plus récent (je ne sais pas si ça a à voir avec mon problème), j'ai pu compiler Script2 avec l'option CUI et fais un test en lignes de commande : ça fonctionne. Je modifie un peu Script1 pour qu'il écrive sur le bloc note ce que je souhaite (en remplaçant ConsoleWrite par Send), reviens sur le 1er PC et ça ne fonctionne pas...
Après plusieurs essais, j'ai trouvé d'où vient le problème, je ne sais pas comment le résoudre et ça m'embête...
Au début de Script1, je demande à l'utilisateur de choisir un répertoire que je stock dans la variable
$repertoire (Bureau\File). Dans celui-ci doit se trouver Script2.exe (contrainte forte de mon tuteur). J'ai donc modifié le Run pour qu'il aille chercher Script2.exe dans
$repertoire.
Code : Tout sélectionner
Local $pid = Run("Script2.exe nom", $repertoire, @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD)
Le problème est qu'il ne trouve pas Script2.exe... Lorsque je copie Script2.exe dans le même dossier que Script1.exe (sur le bureau) en gardant
$repertoire au lieu de
@ScriptDir, ça fonctionne... Et comme je disais, cela m'embête parce que Script2 n'est pas censé se trouver dans le même répertoire que Script1 :/
EDIT : J'ai fais autrement et ça fonctionne...
Code : Tout sélectionner
Local $pid = Run($repertoire & "\Script2.exe nom", "", @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD)
EDIT 2 : J'anticipe un peu : s'il me dit que ça ne lui va toujours pas, est-ce qu'il y a une autre solution ?
Re: [..] Connaître le Return d'un executable
Posté : ven. 17 juil. 2015 14:48
par caropost
Ca convient, merci pour votre aide
