Déterminer la fin d’un processus Shell
Lorsque vous exécutez la fonction Shell dans une procédure Visual Basic pour Applications (VBA), elle démarre un programme exécutable de façon asynchrone et retourne le contrôle à la procédure. Ce programme Shell continue de s'exécuter indépendamment de votre procédure jusqu'à ce que vous la fermiez.
Si votre procédure doit attendre la fin du processus Shell, vous pouvez utiliser l'API de Windows pour chercher le statut de l'application, mais cela n'est pas très efficace. Cette rubrique vous explique une méthode plus efficace.
L'API de Windows intègre une fonctionnalité qui permet à votre application d'attendre la fin d'un processus Shell. Pour utiliser ces fonctions, vous devez disposer d'une poignée sur le processus Shell. Pour cela, utilisez la fonction CreateProcess au lieu de la fonction Shell pour commencer votre programme Shell.
Créer le processus interpréteur de commandes
Pour créer un processus adressable, utilisez la fonction CreateProcess pour démarrer votre application Shell. La fonction CreateProcess donne à votre programme le handle du processus Shell via un de ses paramètres transmis.
Attendez la fin du processus shellé
Vous pouvez transmettre cette poignée à la fonction WaitForSingleObject après avoir utilisé la fonction CreateProcess pour obtenir un descripteur de processus. Votre procédure VBA suspend alors son exécution jusqu'à la fin du processus Shell.
Les étapes suivantes sont nécessaires pour générer une procédure VBA qui utilise la fonction CreateProcess pour exécuter l’application Windows Notepad. Ce code montre comment utiliser les fonctions CreateProcess et WaitForSingleObject de l'API de Windows pour attendre la fin d'un processus Shell avant de reprendre l'exécution.
La syntaxe de la fonction CreateProcess étant complexe, dans l’exemple de code, elle est encapsulée dans une fonction appelée ExecCmd. ExecCmd prend un paramètre, la ligne de commande de l’application à exécuter.
Créez un module standard et collez les lignes suivantes dans la section Déclarations :
Option Explicit Private Type STARTUPINFO cb As Long lpReserved As String lpDesktop As String lpTitle As String dwX As Long dwY As Long dwXSize As Long dwYSize As Long dwXCountChars As Long dwYCountChars As Long dwFillAttribute As Long dwFlags As Long wShowWindow As Integer cbReserved2 As Integer lpReserved2 As Long hStdInput As Long hStdOutput As Long hStdError As Long End Type Private Type PROCESS_INFORMATION hProcess As Long hThread As Long dwProcessID As Long dwThreadID As Long End Type Private Declare Function WaitForSingleObject Lib "kernel32" (ByVal _ hHandle As Long, ByVal dwMilliseconds As Long) As Long Private Declare Function CreateProcessA Lib "kernel32" (ByVal _ lpApplicationName As Long, ByVal lpCommandLine As String, ByVal _ lpProcessAttributes As Long, ByVal lpThreadAttributes As Long, _ ByVal bInheritHandles As Long, ByVal dwCreationFlags As Long, _ ByVal lpEnvironment As Long, ByVal lpCurrentDirectory As Long, _ lpStartupInfo As STARTUPINFO, lpProcessInformation As _ PROCESS_INFORMATION) As Long Private Declare Function CloseHandle Lib "kernel32" (ByVal _ hObject As Long) As Long Private Const NORMAL_PRIORITY_CLASS = &H20& Private Const INFINITE = -1&
Collez le code suivant dans le module :
Public Sub ExecCmd(cmdline As String) Dim proc As PROCESS_INFORMATION Dim start As STARTUPINFO Dim ReturnValue As Integer ' Initialize the STARTUPINFO structure: start.cb = Len(start) ' Start the shelled application: ReturnValue = CreateProcessA(0&, cmdline$, 0&, 0&, 1&, _ NORMAL_PRIORITY_CLASS, 0&, 0&, start, proc) ' Wait for the shelled application to finish: Do ReturnValue = WaitForSingleObject(proc.hProcess, 0) DoEvents Loop Until ReturnValue <> 258 ReturnValue = CloseHandle(proc.hProcess) End Sub
Pour tester la fonction, collez le code suivant dans la fenêtre Exécution et appuyez sur Entrée. Le Bloc-notes démarre. Après un instant, fermez le Bloc-notes. La boîte de message s’affiche lorsque le Bloc-notes se ferme.
ExecCmd "NOTEPAD.EXE": MsgBox "Process Finished"
Assistance et commentaires
Avez-vous des questions ou des commentaires sur Office VBA ou sur cette documentation ? Consultez la rubrique concernant l’assistance pour Office VBA et l’envoi de commentaires afin d’obtenir des instructions pour recevoir une assistance et envoyer vos commentaires.