rzmitri
Messages postés11Date d'inscriptionmercredi 16 mars 2005StatutMembreDernière intervention 4 janvier 2008
-
3 janv. 2008 à 15:02
rzmitri
Messages postés11Date d'inscriptionmercredi 16 mars 2005StatutMembreDernière intervention 4 janvier 2008
-
4 janv. 2008 à 21:02
Bonjour,
J'utilise ce bout que j'ai trouvé quelque part pour lancer des batch file sur plusieurs ordinateur en même temps:
Private Declare Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessID As Long) As Long
Private Const SYNCHRONIZE = &H100000
Private Const WAIT_TIMEOUT = &H102&
Function burn_it(machine_name As String) As Boolean
Do While retour = WAIT_TIMEOUT
retour = WaitForSingleObject(ProcessHandle, 1)
DoEvents
Loop
retour = CloseHandle(ProcessHandle)
strmsgbox = LireFichier(machine_name)
Debug.Print strmsgbox
End Function
La fonction LireFichier récupère les fichiers texte qui sont crées sur les machines distante à la fin de l'exécution de chaque batch et lit le test contenu dans ce fichier.
L'ennui est que la lecture des fichiers text ne se fait que lorsque tous les batchs sur toutes les machines aient terminé.
J'aimerai que la lecture du fichier text se fasse à la fin de chaque batch
rzmitri
Messages postés11Date d'inscriptionmercredi 16 mars 2005StatutMembreDernière intervention 4 janvier 2008 3 janv. 2008 à 15:48
justement, ça marche bien lorsque je lance la fonction une seule fois mais quand je la lance plusieurs fois la lecture des fichiers ne se fait qu'à la fin de l'exécution du dernier .bat...
rzmitri
Messages postés11Date d'inscriptionmercredi 16 mars 2005StatutMembreDernière intervention 4 janvier 2008 3 janv. 2008 à 16:30
Ils se lancent rapidment par contre l'exécution prend quelques secondes (environ 10 à 20) et les debug ne commencent qu'à la fin.
Si je mets un point d'arrêt il y a un seul debug qui se fait, les autres après continuation se font avec l'heure de la réexécution.
Je t'explique un peu comment ça marche: j'ai un formulaire avec 5 boutons, chaque bouton lance la fonction avec comme paramètre le nom de la machine. Si je mets chaque bouton dans une form à part, ça fonctionne parfaitement !
rzmitri
Messages postés11Date d'inscriptionmercredi 16 mars 2005StatutMembreDernière intervention 4 janvier 2008 3 janv. 2008 à 16:57
Voici tout le code en question:
Option Compare Database
Option Explicit
Rem declaration des api qui permettent d'attendre la fin de l'execution avant de passer a autre chose
Private Declare Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessID As Long) As Long
Private Const SYNCHRONIZE = &H100000
Private Const WAIT_TIMEOUT = &H102&
Function Copy_it(machine_name As String) As String
Dim strmsgbox As String
Dim Démarre, ProcessHandle, retour
rzmitri
Messages postés11Date d'inscriptionmercredi 16 mars 2005StatutMembreDernière intervention 4 janvier 2008 3 janv. 2008 à 19:14
J'ai retesté le code avec des .bat qui prennent bcq plus de temps (entre 5 et 10 min) , à la fin du premier batch, il y a un debug qui se fait, les autres se font tous en même temps à la fin d'exécution du dernier
rzmitri
Messages postés11Date d'inscriptionmercredi 16 mars 2005StatutMembreDernière intervention 4 janvier 2008 4 janv. 2008 à 10:58
Réponse reçu sur un newsgroup de Jean-marc Noury (jean_marc_n2)
Microsoft MVP - Visual Basic
FAQ VB: http://faq.vb.free.fr/
C'est un peu compliqué par ce que tu veux en même temps un
fonctionnement SYNCHRONE (attendre la fin d'exécution pour lire
le batch) et ASYNCHRONE (par ce que tu lances plusieurs process).
En plus, les process eux même sont lancés de façon asynchrone
(clic sur un bouton) MAIS lancés par la même fonction...
On tourne en rond.
Je ne suis pas sur qu'il y ait une vraie solution viable sans
utiliser de vrais threads, ce qui est un cauchemard à faire
en VB (à cause de l'instabilité dans l'IDE entre autre).
Peut être que la bonne solution est de faire un lancement
asynchrone de tous les process et de récupérer les fichiers
de log par un polling.
Je pense que c'est ce que je ferais, sans connaitre toutes
tes contraintes bien sur.
Renfield
Messages postés17287Date d'inscriptionmercredi 2 janvier 2002StatutModérateurDernière intervention27 septembre 202174 4 janv. 2008 à 11:04
ah ! je ne savais pas que tu t'amusais a en lancer plusieurs en même temps...
normallement pas de soucis, remarque, (a part tes variables qui ne sont pas typées)
puisque bien qu'executant la même fonction plusieurs fois, les variables sont propres a la fonction....
Renfield
Messages postés17287Date d'inscriptionmercredi 2 janvier 2002StatutModérateurDernière intervention27 septembre 202174 4 janv. 2008 à 11:25
J'ai fait le test, en utilisant des fichiers BAT qui font ce genre de choses, sur divers dossiers, pour que le temps de traitement soit different :
Dir C:\Windows\system32 /s > C:\Machine_0_log.txt
J'ai testé en utilisant ton code, remanié pour la propreté de la chose:
Private Declare Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessID As Long) As Long
Private Const SYNCHRONIZE = &H100000
Private Const WAIT_TIMEOUT = &H102&
Public Function Copy_it(ByRef vsMachineName As String) As String
Dim nPID As Long
Dim hProcess As Long
On Local Error Resume Next
nPID = Shell("C:" & vsMachineName & "_batch.bat", vbNormalNoFocus)
If nPID Then
hProcess = OpenProcess(SYNCHRONIZE, False, nPID)
If hProcess <> -1 Then
Do
DoEvents
Loop While WaitForSingleObject(hProcess, 200) = WAIT_TIMEOUT
CloseHandle hProcess
'Copy_it = LireFichier("\" & vsMachineName & "" & "c$" & vsMachineName & "_log.txt")
Copy_it = LireFichier("C:" & vsMachineName & "_log.txt")
Debug.Print Now, vsMachineName & ": ", Left$(Copy_it, 50)
End If
End If
End Function
Public Function LireFichier(ByRef vsPath As String) As String
Dim iFile As Integer
Dim xbData() As Byte
If Dir$(vsPath) <> vbNullString Then
iFile = FreeFile
Open vsPath For Binary Access Read As iFile
ReDim xbData(LOF(iFile))
Get iFile, , xbData
Close iFile
LireFichier = StrConv(xbData, vbUnicode)
End If
End Function
Private Sub Command1_Click(Index As Integer)
Copy_it "Machine_" & Index
End Sub
mais je n'ai pas eu de soucis....
pourtant, j'ai cliqué comme un forcené ^^
jmfmarques
Messages postés7666Date d'inscriptionsamedi 5 novembre 2005StatutMembreDernière intervention22 août 201427 4 janv. 2008 à 11:44
Bonjour Rernfields,
C'est tout simplement parce que tout allait très vite et qu'il ne voyait que la dernière ligne...
Il a été invité à envoyer vers une textbox ===>> tout se déroule bien séquentiellement ....
Reste que l'affichage lui-même prend un peu de temps et qu'un simple doevents lui permet d'y voir plus clair...