Bonsoir
Pour ma part je sais lancer un exe depuis du html.
Le soucis est donc de lancer un exe externe puis de le faire dialoguer avec
le premier qui gère la gui.
Pour ceci nous avons 2 moyens :
- Le dialogue par fichiers tamporaires
- Le partage directe de variable par pointeur
Du fait qu'il y a une problématique d'accès concurent (du genre, on clique sur 2
actions l'une après l'autre, aolors que la première action n'est pas terminée)
il vaut mieux oper pour la deuxième méthode.
pour faire ceci, il faut :
1 script gérant la gui incluant l'objet html, exe '1'
1 fichier index.html lançant l'éxécuitable '2' via des liens href en donnant le nom de l'action en argument
1 script '2' dit de notification qui va renvoyer les info vers le script gérant la gui (premier point)
Mais alors comment faire pour faire dialoguer 2 exe dans un même espace d'adresage ?
Et bien en prenant l'udf memory2.au3 exposée ici :
http://www.autoitscript.fr/forum/viewto ... f=11&t=846
Cependant pour réaliser ceci,il faut indiquer à l'exe notifieur '2' ,le nom de l'action àeffectuer
le PID de l'exe GUI '1' , 1 pointeur vers un buffeur qui contiendra l'action cliquée
afin de faire un traitement dans '1', 1 pointeur vers un int qui indiquera si
le service de traitement de '1' est libre ou en train de travailler
Le soucis est que le pid, comme les pointeurs ne sont pas déterminable à l'avance.
Donc il faut que le script '1' se serve du fichier indexhtml de base pour en faire une
copie enrichie avec ces infos lors de sont éxécution.
Ainsi l'exe '2' va pouvoir écrire dans les pointeurs de '1' le nom de l'action
à effectuer et basculer l'état de libre à occuper pour créer une sémaphorisation.
Le script '1' tournant en boucle infini, et testant en permanence la valeur du pointeur
va se retrouver d'un coups avec une action à faire, et va la traiter.
En fin de traitement, le script '1' rebascule son état à libre, pour les autres instances du
scripts '2'
Donc pour faire plus simple :
1) on modifie index.html pour créer autant de liens vers le script 2, appeler
ici doaction suivit du nom de la commande à effectuer
2) on compile doaction.au3 en doaction.exe, dans le même rep
3) on lance main_gui.au3, attention, au premier click on a l'avertissement classique de l'activeX
de lancement d'appli qui s'affiche, après il n'intervient plus.
Note importante (pour finir et bravo à ceux qui sont arrivé là) : les actions ici sont appelées
dans le script '1' via call(nom_fonction). Faites en sorte de lancer un Run idépendant, et non un déroulement
de code, car le déroulement bloque la GUI. Grâce aux Run d'exe indépendants,
on arrive à un service ressemblant à du multitâche, plus éfficace dans de nombreux cas.
Bon courrage
index.html :
► Afficher le texte
Code : Tout sélectionner
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<SCRIPT LANGUAGE="javascript">
<!--
function OuvreExecutable(e)
{
var w = new ActiveXObject("WScript.Shell");
w.run (e);
}
// -->
</SCRIPT>
<meta http-equiv="content-type" content="text/html; charset=windows-1250">
<meta name="generator" content="PSPad editor, http://www.pspad.com">
<title></title>
</head>
<body>
machine 1 : <a href="#" OnClick="OuvreExecutable('D:\\moi\\script_au3\\html_action\\doaction.exe action1')">action 1</a> <br>
machine 2 : <a href="#" OnClick="OuvreExecutable('D:\\moi\\script_au3\\html_action\\doaction.exe action2')">action 2</a> <br>
machine 3 : <a href="#" OnClick="OuvreExecutable('D:\\moi\\script_au3\\html_action\\doaction.exe action3')">action 3</a> <br>
</body>
</html>
doaction.au3 :
► Afficher le texte
Code : Tout sélectionner
;file to modifie action pointer for main_gui
#include "memory2.au3" ; librairie de gestion de memoire en RAM
$title_dataintern=@ScriptDir&"\dataintern"
$action = ""
$FREE = 0
$BUSY = 1
If 4 = $CmdLine[0] Then
$action = $CmdLine[1]
$pid = $CmdLine[2]
$ptr_buffer=Ptr($CmdLine[3])
$ptr_status = Ptr($CmdLine[4])
Else
Exit 1
EndIf
;petit ctrl d'argument :
If ( Not ProcessExists($pid) ) Or ( 0 = $ptr_buffer ) Or ( 0 = $ptr_status ) Then Exit 2
; on fait une sorte de file d'attente non régulée en cas de non disponibilité du pointeur
While readmemory($pid,$ptr_status) <> $FREE
Sleep(1000)
WEnd
; OK c'est notre tours ! on notifie qu'on a pris le ticket
updatememory($pid,$ptr_status,"int",$BUSY) ;on passe en mode busy
updatememory($pid,$ptr_buffer,"char[50]",$action) ; on envoie la chaîne actionx à la GUI
Exit 0
Func updatememory($process_id,$adress_mem,$type,$val)
;Local $offset=0
Local $DllHandle = _MemoryOpen($process_id); on ouvre la partie de mémoire utilisée par le pid de l'appelant
Local $Data = _MemoryWrite($adress_mem, $DllHandle,$val,$type); on écrit à l'adresse passer en arg la valeur typée en int (type original de la valeures dont l'adresse a été passée)
_MemoryClose($DllHandle) ;on referme le handle ouvert sur cette zone
EndFunc
Func readmemory($process_id,$adress_mem)
Local $DllHandle = _MemoryOpen($process_id); on ouvre la partie de mémoire utilisée par le pid de l'appelant
Local $val_ret=0
$val_ret = _MemoryRead($adress_mem, $DllHandle, "int")
_MemoryClose($DllHandle) ;on referme le handle ouvert sur cette zone
Return $val_ret
EndFunc
main_gui.au3 :
► Afficher le texte
Code : Tout sélectionner
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#Include <Misc.au3>
_Singleton(@ScriptName); n'authorise qu'une occurence de ce programme
;creation du pointeur qui contiendra le nom de l'action
$structbuffer=DllStructCreate("char bufferaction[50];int status")
If $structbuffer = 0 Then Exit 1
DllStructSetData($structbuffer,"bufferaction","")
$ptr_bufferaction=DllStructGetPtr($structbuffer,"bufferaction")
If 0 = $ptr_bufferaction Then Exit 2
$FREE = 0
$BUSY = 1
DllStructSetData($structbuffer,"status",$FREE)
$ptr_status = DllStructGetPtr($structbuffer,"status")
If 0 = $ptr_status Then Exit 3
;on localise les appels à l'exe pour les compléter des arguments :
; pid, pointeur action, pointeur status
;attention, je ne vais pas entré dans les détails des expr regulières, si il y a besoins on repostera :-p
FileCopy("index.html","index_modified.html",1)
$contenu = FileRead("index_modified.html")
$modified=StringRegExpReplace($contenu,"('\)"&'">[^<]+</a>)'," "&@AutoItPID&" "&$ptr_bufferaction&" "&$ptr_status&" $1")
;on met à jour le chemin abdolu par rapport au chemin actuellement executé
; celà permet de garder le même index.html d'un rep à l'autre sans avoir à modifier le chemin absolu
$truepath=StringReplace(@ScriptDir,"\","\\\\")
$truepath&="\\\\"
ConsoleWrite($truepath)
$modified=StringRegExpReplace($modified,"'.*\\\\([^\\]+\.exe)","'"&$truepath&"$1")
$hnd_modified=FileOpen("index_modified.html",2)
FileWrite($hnd_modified,$modified)
FileClose($hnd_modified)
#Region ### START Koda GUI section ### Form=
$Form1 = GUICreate("Form1", 650, 472, 193, 115)
$oIE = ObjCreate("Shell.Explorer.1")
If @error Then Exit 1
$ctrl_IE= GUICtrlCreateObj ($oIE, 30, 40, 600, 360)
$oIE.Navigate(@ScriptDir&"\index_modified.html")
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###
While 1
$nMsg = GUIGetMsg()
Switch $nMsg
Case $GUI_EVENT_CLOSE
Exit
EndSwitch
$command = DllStructGetData($structbuffer,"bufferaction"); on guette la valeur stockée de bufferaction potentiellement modifiée par doaction
If $command<>"" Then
Call($command)
;on a fini le traitement donc on réinitialise la commande à executer et le status
DllStructSetData($structbuffer,"bufferaction","")
DllStructSetData($structbuffer,"status",$FREE)
EndIf
WEnd
$oIE.destroye()
FileDelete("index_modified.html")
Exit 0 ;fin
;fonctions à lancer : attention ces actions étant écrite dans le même script que la GUI, vont monopoliser le tps cpu vis à vis de la GUI
; il serait bon de lancer des "Run" vers des exe tierces avec arguments (eux mêmes pouvant être en autoit ...)
Func action1()
MsgBox(0,"test","action1")
EndFunc
Func action2()
MsgBox(0,"test","action2")
EndFunc
Func action3()
MsgBox(0,"test","action3")
EndFunc