Bonjour
J'ai un soucis qui me parait vraiment très pointu, et je soupçonne là un bug dans autoit : Dans certaines condition, l'exploitation du résultat d'une commande run à l'aide d'une boucle qui scanne le résultat avec stdoutread se fige.
J'ai donc écrit le script suivant pour essayer d'affiner le soucis:
► Afficher le texte
Code : Tout sélectionner
;; #include "ServiceControl.au3"
; variables globales
Const $MAITRE=@ComputerName
$ESCLAVE=""
$COMPTEUR=0
$STATUT=""
Const $INIBOUCLE=300 ; nombre de fois où l'on scan un service "starting" ou "stopping" avant de tomber en erreur.
Const $DELAIBOUCLE=1100 ; temps d'attente entre chaque scan de l'état d'un service "starting" ou "stopping".
Const $ESPEXEC_WANTED=15 ; nombre de processus "espexec.exe" sensés être présents à l'issue du démarrage du maitre.
$SERVICENAME="RemoteRegistry" ; Utilisation de ces PC et de ce service pour la mise au point du programme.
Switch $MAITRE
Case "machine1"
$ESCLAVE="machine2"
Case Else
ConsoleWriteError("Erreur" & @CRLF)
exit 8
EndSwitch
Func now()
Return ( @MDAY & "/" & @MON & "/" & @YEAR & " " & @HOUR & ":" & @MIN & ":" & @SEC & ": ")
EndFunc
Func action_service($ACTION,$NOMSERVICE,$SERVEUR="")
If $SERVEUR<>"" Then
$TESTPING=Ping($SERVEUR,5)
If $TESTPING=0 Then
Return("Erreur Serveur HS")
EndIf
$SERVEUR=" \\" & $SERVEUR
EndIf
$PID=Run(@SystemDir & "\sc.exe" & $SERVEUR & " " & $ACTION & " " & $NOMSERVICE,@TempDir,@SW_HIDE,2)
$RESULTAT=""
$CPTBCL=300000
Do
$CPTBCL-=1
$BLOCK=StdoutRead($PID)
If @error Then ExitLoop
$RESULTAT&=$BLOCK
Until (@error) Or ( $CPTBCL<=0 )
Sleep(100)
If $CPTBCL<=0 Then
ConsoleWriteError(@CRLF & now() & "Sortie de boucle forcée en attente d'une commande sc.exe!" & @CRLF & "On va tenter la suppression du process SC " & @CRLF )
EndIf
If ProcessExists($PID) Then
ConsoleWriteError(@CRLF & now() & "Attention, l'analyse du resultat de sc est finie, mais le process sc a survécu!!" & @CRLF & " Entree dans boucle d'attente" & @CRLF)
ProcessWaitClose($PID,20)
If ProcessExists($PID) Then
ConsoleWriteError(now() & "Process sc.exe toujours vivant, tentative de kill" & @CRLF)
If ProcessClose($PID) Then
ConsoleWriteError(now() & "Process sc.exe tué" & @CRLF)
Else
ConsoleWriteError(now() & "echec kill Process sc " & $PID & "erreur=" & @error & @CRLF)
exit 6
EndIf
EndIf
ConsoleWriteError(now() & "Abandon de l'analyse, voici le résultat brut:" & @CRLF & $RESULTAT & @CRLF & @CRLF)
Return("Erreur commande SC")
EndIf
$ANALYSE=StringSplit($RESULTAT,@CRLF,1)
$CHECKOK=0
For $CPT=1 To $ANALYSE[0]
If StringInStr($ANALYSE[$CPT],"state") Then
$RESULTAT=$ANALYSE[$CPT]
$CHECKOK=1
ExitLoop
EndIf
Next
If $CHECKOK=0 Then
ConsoleWriteError( @CRLF & now() & "Retour commande sc " & $ACTION & " non reconnu: " & $RESULTAT & @CRLF )
Return("Retour commande sc " & $ACTION & " non reconnu: " & $RESULTAT)
EndIf
$ANALYSE=StringSplit($RESULTAT,":")
If $ANALYSE[0]<>2 Then
ConsoleWriteError( @CRLF & now() & "Erreur analyse retour : " & $RESULTAT & @CRLF )
Return("Erreur analyse retour : " & $RESULTAT)
EndIf
; POUR DEBUGAGE
ConsoleWrite(@CRLF & now() & "attente SC=" & 300000-$CPTBCL & ",résultat analyse=" & $ANALYSE[2] & @CRLF)
Return($ANALYSE[2])
EndFunc
While 1
$STATUT=action_service("query",$SERVICENAME,$ESCLAVE)
ConsoleWrite(".")
sleep($DELAIBOUCLE)
WEnd
Le programme est compilé en mode console.
Vous pouvez essayer le script chez vous, après avoir renseigné "machine1" et "machine2" avec le nom de 2 PC. L'idée étant de scanner le résultat d'une commande SC distante ( donc machine1<> machine2 ).
Pour ma part, ce script fonctionne parfaitement entre 2 machines windows XP SP3 (il a tourné toute la nuit) , mais se fige de façon aléatoire entre 2 machines windows 2003 server.
Quand ça se fige, l'utilisation du CTRL+C ne termine pas le programme ( alors que CTRL+C termine le programme quand il n'est pas figé ). Le kill via le gestionnaire de tâche reste heureusement possible.
Quand c'est figé, l'icone du programme autoit ( que je n'ai pas customisée ni masquée ) est également figée : impossible de terminer le programme via cette icône ni même d'obtenir le menu par défaut via un clic de souris. ( et ça, ça penche en faveur d'un bug autoit non ? )
Quand le programme est figé, il n'y a pas de process SC.EXE "fils" du programme.
Le freeze peut survenir n'importe quand: après 2 itérations comme 200...
A priori, sous windows 2003, ça ne se fige que quand SC est lancé pour obtenir le résultat d'une machine distante, mais c'est peut-être un hasard
Là, c'est compilé avec autoit v3.3.40. J'imagine que je vais devoir commencer par compiler ça avec la dernière version,
[edit] Recompilé en mode console avec autoit v3.3.61 et recompilé --> le problème reste entier.
[edit bis] Test croisé : la machine W2003 fait un SC d'un service présent sur une machine winXP et vice-versa. le freeze se produit toujours sur la machine w2003.
[edit ter] la récupération de SC.exe version windows XP et utilisation sur windows 2003 ne change rien.
SC.exe version windows XP : 5.1.2600.5755
SC.exe verion windows 2003 : 5.2.3790.4455
De plus SC.exe version windows 2003 ne fonctionne pas sous windows XP : on obtient rien en retour (mais SC.exe version windows XP fonctionne sous 2003)
Je suis toujours preneur d'infos intéressantes à ce sujet.
Merci d'avance
