Visual Basic Script
Version de VBScript : à partir de la 5.6. Systèmes d'exploitation concernés :
Windows XP, Windows 7 (pourquoi pas Vista)
accueil | console |
VBScript | PowerShell
| php | MySQL |
documentation |
formation |
trucs et astuces |
exemples |
glossaire

Généralités
La
gestion d'erreurs dans l'environnement
VBScript
Programmation de la gestion des erreurs dans un script
VBScript
Error Handler en environnement
VBScript
Journalisation des erreurs en environnement
VBScript
I - GENERALITES
Visual Basic,
Scripting Edition (en abrégé VBScript) est un moteur de scripts interprété
qui permet une gestion puissante de Windows, beaucoup plus complète que ne
le permettait (et le permet encore) la Console de
lignes de commandes.
La syntaxe de
VBScript est très semblable à Visual Basic, avec quelques
limitations, dont notamment l'absence (à notre avis
regrettable) de l'instruction GOTO et de la capacité de
connaître le numéro d'une ligne en cours d'exécution (l'un étant
probablement une conséquence de l'autre).
VBScript
est puissant car il dispose d'un interface immédiat et relativement facile à
programmer vers le Windows Management Instrumentation (WMI),
infrastructure de gestion de Windows orientée objets, avec laquelle on peut
pratiquement tout faire, en local ou sur une machine distante.
Remarque : Pour tout ce qui suit, une connaissance
minimum de VBScript est supposée être acquise, notamment pour ce qui
concerne la différence entre l'utilisation des moteurs wscript et
cscript.
[début]
II - LA GESTION D'ERREURS
DANS L'ENVIRONNEMENT VBScript
La gestion des erreurs avec
VBScript est simplissime (d'où la création de ce site,
doit-on le répéter).
Soit on n'en veut pas, on ne fait
rien de spécial dans le script et celui-ci s'arrête dès la première erreur,
soit on en veut et on utilise l'instruction :
On Error Resume Next
L'instruction On Error Resume
Next crée de façon interne un objet Err dont l'une des
propriétés, Err.Number, contiendra le numéro de l'erreur s'il en
survient une, puis indique à l'interpréteur de scripts d'ignorer purement et
simplement toute erreur rencontrée et de passer à la ligne suivante.
L'annulation de l'action de On
Error Resume Next se fait par l'instruction :
On Error goto 0
Exemple :
oern.vbs
' démonstration de l'utilisation de
On Error Resume Next (en abrégé OERN)
Option Explicit 'toutes les variables
doivent être définies
Wscript.Echo vbcrlf & "1. Activation de OERN"
On Error Resume next 'les erreurs doivent être
ignorées
Wscript.Echo "2. Production d'une erreur volontaire (variable myVar non
définie)"
Wscript.Echo myVar 'erreur car myVar n'est pas
définie
Wscript.Echo "** Il y a eu une erreur mais c'est pas grave"
Wscript.Echo vbcrlf & "3. Désactivation de OERN"
On Error goto 0 'annulation de l'action de
OERN
Wscript.Echo "4. Production d'une erreur volontaire (variable myVar non
définie)"
Wscript.Echo myVar 'erreur car myVar n'est pas
définie
Wscript.Echo "** Le script n'exécutera jamais cette ligne"
Wscript.Quit
Résultat :
C:\vbs>oern
1. Activation de OERN
2. Production d'une erreur volontaire (variable myVar non définie)
** Il y a eu une erreur mais c'est pas grave
3. Désactivation de OERN
4. Production d'une erreur volontaire (variable myVar non définie)
C:\vbs\oern.vbs(14, 1) Erreur d'exécution Microsoft VBScript: Variable non
définie: 'myVar'
C:\vbs>
[début]
III - PROGRAMMATION
DE LA GESTION DES ERREURS DANS UN SCRIPT VBScript
Les scripts VBScript (en abrégé
VBS) exécutés depuis la console (par les programmes wscript.exe
ou cscript.exe)
doivent porter l'extension .vbs. Ils ne peuvent contenir que des
instructions spécifiques au langage Visual Basic Script. Ce langage
est interprété, ce qui signifie que d'éventuelles erreurs de syntaxe
ou de programmation sont détectées au lancement du script juste avant son
exécution.
a) Un script VBS retourne à la
console la valeur param dans la variable ERRORLEVEL selon
l'instruction finale suivante :
wscript.quit param
b) Un script VBS renvoie à la
console dans la
variable ERRORLEVEL la valeur 1 si une erreur de syntaxe se produit
au moment de son interprétation
Exemple :
syntax_error.vbs
a = 0
if a = 0 wscript.quit ' "Then" est manquant
Résultat :
C:\vbs>cscript /nologo
syntax_error.vbs
C:\vbs\syntax_error.vbs(2, 10) Erreur de compilation Microsoft
VBScript : 'Then' attendu
C:\vbs>echo %errorlevel%
1
Remarque 1 : Les erreurs de
syntaxe ne sont pas gérables par la fonction on error resume next (ni
par rien d'autre, soit dit en passant)
Remarque 2 : L'interpréteur
indique entre parenthèses le numéro de la ligne et le quantième du premier
caractère où a été détectée l'erreur.
On utilisera avantageusement l'outil
Line_Numbers.vbs pour numéroter
les lignes d'un grand fichier source.
c) Un script VBS renvoie dans la
variable système Err.Number un numéro VBS unique d'erreur au moment de son exécution si l'on a programmé la gestion des erreurs au moyen de
l'instruction on error resume next, sinon le script s'arrête avec un
code retour positionné à 1 (en savoir plus sur l'utilisation de
l'instruction on error resume next
ici.)
Exemple :
runtime_error.vbs
on error resume next
set WshShell = WScript.CreateObject("WScript.Shell")
WshShell.Run "%windir%\notepad " & toto.txt
'la commande attend une variable, pas un nom
wscript.echo "Erreur : " & err.number
wscript.echo "Description : " & err.description
wscript.echo "Source : " & err.source
wscript.quit
Résultat :
C:\vbs>cscript /nologo
runtime_error.vbs
Erreur : 424
Description : Objet requis
Source : Erreur d'exécution Microsoft VBScript
d) Un script VBS renvoie des
informations complémentaires sur une erreur si l'on a utilisé un appel au
Windows Management Instrumentation (WMI) via la commande
Set WMI_Error
= CreateObject("WbemScripting.SwbemLastError")
Exemple :
wmi_error_demo.vbs
set objWMIService =
getObject("winmgmts:root\CIMV2")
on error resume next
set objShare = objWMIService.Get("Win32_Printer.DeviceID='TestPrinter'") ' n'existe pas
if err.number <> 0 then ' (la syntaxe
if err <> 0 est également
valable)
ern = err.number and &HFFFF& ' supprime les 4 premiers bits
inutilisés (en savoir plus)
wscript.echo "WSH Error : " & ern &
vbcrlf & _
"WSH Error (Hex): " & Hex(err.number) & vbcrlf & _
"WSH Description: " & err.description & vbcrlf & _
"WSH Source : " & err.source
set WMI_Error = CreateObject("WbemScripting.SwbemLastError")
Wscript.Echo "WMI Operation : " & WMI_Error.Operation &
vbcrlf & _
"WMI Parameter : " & WMI_Error.ParameterInfo & Vbcrlf & _
"WMI Provider : " & WMI_Error.ProviderName
end if
wscript.quit
Résultat :
C:\vbs>cscript /nologo
wmi_error_demo.vbs
WSH Error
: 4098
WSH Error (Hex): 80041002
WSH Description: Non trouvé
WSH Source : SWbemServicesEx
WMI Operation : GetObject
WMI Parameter : Win32_Printer.DeviceID="TestPrinter"
WMI Provider : CIMWin32
e) L'instruction on error
resume next placée en début de script couvre intégralement celui-ci sauf les fonctions et les subroutines. Si l'on
veut aussi (et c'est hautement souhaitable) gérer les erreurs
d'exécution qui pourraient advenir dans le code d'une fonction ou d'une
subroutine, celles-ci doivent également commencer chacune par activer l'objet
Err au moyen de l'instruction on error resume next
(en savoir plus sur l'objet Err
ici.)
f) Chaque exécution d'un code de
gestion d'erreur doit se terminer par la remise à zéro de ce code, sinon -
puisque c'est un objet et non une simple variable -, les propriétés de cet
objet sont conservées pendant toute la durée de son instanciation (de son
activation, si vous ne parlez pas
OOP :-) Cette remise à zéro se fait avec
l'instruction Err.Clear
Exemple :
On Error Resume Next
Err.Raise 6 ' Raise an overflow error.
MsgBox "Error # " & Err.Number & " " & Err.Description
Err.Clear ' Clear the error.
g) L'objet Err conserve
ses propriétés dans une fonction et une subroutine. C'est ce que l'on
appelle avoir un scope global. Une variable déclarée dans une
fonction ou une subroutine, elle, n'est pas définie dans le programme
principal qui l'a appelée. Elle a un
scope local. L'objet
Err ayant un scope global, il n'est pas nécessaire de passer la variable
Err.Number comme paramètre à une fonction ou à une subroutine de
gestion d'erreurs.
Exemple :
On Error Resume Next
strComputer = "fictional"
strPrinter = "TestPrinter"
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
If Err = 0 Then 'same as "if Err.Number =
0" because default value for object Err
WScript.Echo "No error binding to " & strComputer
strPrinter = "TestPrinter"
Set objPrinter = objWMIService.Get ("Win32_Printer.Name='" & strPrinter &
"'")
If Err = 0 Then
WScript.Echo "No error connecting to " & strPrinter
Else
call DisplayErrorInfo
End If
Else
call DisplayErrorInfo
End If
'******************************************************************************
Sub DisplayErrorInfo
WScript.Echo "Error: : " & Err
WScript.Echo "Error (hex) : &H" & Hex(Err)
WScript.Echo "Source : " & Err.Source
WScript.Echo "Description : " & Err.Description
Err.Clear
End Sub
Remarque : Pour tout
ce dont on parle ici, il faut garder à l'esprit (ou apprendre) qu'un script exécuté
avec succès en local sur une machine - non membre d'un domaine Microsoft
Windows et à partir d'un compte doté de privilèges
d'administrateur -, ne peut s'exécuter (avec le même succès) à distance sur une
autre machine non membre d'un domaine que si l'utilisateur possède le
même compte avec le même mot de passe et les
mêmes droits sur la machine distante. Si les machines source et destination
sont membres d'un domaine (pas nécessairement le même), il suffit de se
connecter à distance avec un compte administrateur pour contourner cette
difficulté (en
savoir plus).
[début]
IV - ERROR HANDLER EN
ENVIRONNEMENT VBScript
Il n'existe que
deux instructions qui concernent la gestion des erreurs avec VBScript
: On Error Resume Next et On Error goto 0. Malheureusement, il
n'y a pas la possibilité de gérer des erreurs de façon
asynchrone, c'est-à-dire avec des instructions
de type On Error gosub XYZ ou On Error goto XYZ qui n'existent
pas.
Donc la gestion
d'un Error Handler n'en sera que plus simple. On écrit un code de
traitement des erreurs dans une subroutine, on place une instruction
On Error Resume Next
au début du
script pour désactiver la gestion des erreurs par le moteur de script (donc
s'il en advient, le script passe à la ligne suivante sans sourciller), on
teste systématiquement la variable système Err (ou Err.Number,
c'est pareil) et on appelle la subroutine de gestion d'erreur si cette
variable est différente de zéro. C'est ce qui a été montré dans l'exemple
ci-dessus, § g.
Une subroutine de
Error Handler peut être beaucoup plus intéressante - au niveau de
l'information retournée -, dans l'environnement VBScript que dans
l'environnement de la console de lignes de commande,
car la variable Err est en réalité un objet. Cet objet est
doté de deux méthodes et cinq
propriétés (en
savoir plus).
Les deux méthodes de l'objet
Err (actions possibles sur l'objet Err) sont :
Err.Raise
'génère une erreur Run Time
Err.Clear
'reset de l'objet Err
Les cinq propriétés de l'objet
Err sont :
Err.Number
'numéro de l'erreur
Err.Description
'texte descriptif associé
Err.Source
'émetteur de l'erreur (origine)
Err.HelpFile
'spécification complète du nom d'un fichier d'aide éventuel
Err.HelpContext
'clé d'accès à la rubrique du fichier d'aide, si spécifié
La méthode Raise n'a pas
sa place ici, car nous parlons actuellement d'un Error Handler appelé
juste après qu'une erreur est survenue. Le numéro d'erreur sera donc celui
renvoyé par l'émetteur de l'erreur et non un numéro choisi par le
programmeur.
La méthode Clear peut être
utile pour remettre les propriétés de l'objet Err à zéro si on ne
sort pas de la subroutine de gestion des erreurs par un Wscript.Quit 1
(erreur fatale). Sinon elle est inutile.
Parmi les cinq propriétés de
l'objet
Err, les deux dernières sont rarement utilisées car le type de fichier
d'aide ici est l'ancien système, inutilisé depuis Windows XP (fichiers
.HLP). Aujourd'hui, les fichiers d'aide sont des fichiers HTML (fichiers
.CHM) qui ne sont pas accessibles par la combinaison Err.HelpFile
et Err.HelpContext.
Voici un exemple de Error
Handler synchrone :
errmgt.vbs
'------------------------------------------------------------------------
'+
' errmgt.vbs
'
' Error handling management routine to be added at the end of a VBscript.
'
' Usage: call errmgt(action,severity)
'
' Two params should be defined in the caller source: the action performed
and the severity level.
' If error is not fatal, calling code execution is resumed, otherwise
procedure stops.
'
' Note: caller script should be called via Cscript instead of Wscript.
'
' x1.0-0 15-oct-2010 DTL Didier.Morandi at gmail dot com
'-
sub errmgt(WshAction,severity)
if err.number < 0 then
err_nr = Hex(err.number)
else
err_nr = err.number
end if
if WshAction = "" then WshAction = "[missing]"
err_desc = err.description
if err_desc = "" then err_desc = "[missing]"
err_src = err.source
if err_src = "" then err_src = "[missing]"
if err_nr <> 0 then
wscript.echo "WSH>> Error occurred"
if severity = 0 then
'information only
exit sub
else
if severity = 1 then
'warning only
exit sub
else
if severity = 2 then
'non fatal error, script may continue
wscript.echo "WSH Action : " &
WshAction
wscript.echo "WSH Error : " & err_nr
wscript.echo "WSH Descript.: " &
err_desc
wscript.echo "WSH Source : " &
err_src
else
if severity = 4 then
'fatal error, script should stop
wscript.echo "WSH Action
: " & WshAction
wscript.echo "WSH Fatal
error: " & err_nr
wscript.echo "WSH
Description: " & err_desc
wscript.echo "WSH Source
: " & err_src
wscript.quit 1
else
wscript.echo "Invalid
Severity parameter passed to Error Handler" & vbcrlf
end if
end if
end if
end if
end if
end sub
'------------------------------------------------------------------------
'eof errmgt.vbs
Exemple
d'utilisation
Dans l'exemple
qui suit, un script wmi_printer_error.vbs lit les caractéristiques
d'une imprimante inexistante sur un ordinateur inexistant. L'ordinateur
étant inaccessible, l'erreur est fatale et le Error Handler est
appelé une seule fois :
c:\vbs>wmi_printer_error toto titi
* Bind to WMI provider on computer 'TOTO'...
WMI>> GetObject failed
WSH>> Error occurred
WSH Action : GetObject
WSH Fatal error: 462
WSH Description: Le serveur distant n'existe pas ou n'est pas disponible
WSH Source : Erreur d'exécution Microsoft VBScript
Abort.
c:\vbs>
Ensuite, on lit
les caractéristiques d'une imprimante existante sur un ordinateur existant.
L'accès à cette imprimante se fait tout d'abord via son DeviceID.
Tout se passe bien. Mais ensuite il est fait par son nom, ce qui n'est pas
autorisé. WSH renvoie donc une erreur et appelle SWbemLastError
pour en savoir plus. Malheureusement, cet objet n'est pas accessible dans ce
contexte et
WSH renvoie une deuxième erreur afin d'informer l'exploitant, puis
termine le script :
c:\vbs>wmi_printer_error . samsung
* Bind to WMI provider on computer 'PCDIDIER'...
* Bind successful
* Get printer 'SAMSUNG' characteristics by DeviceID
Default
: Vrai
DriverName :
Samsung CLP-310 Series
Horizontal Resolution: 600
Network connection : Faux
Port Name
: USB001
* Get printer 'SAMSUNG' characteristics by Name
WSH>> Error occurred
WSH Action : GetService
WSH Error nr : 8004103A
WSH Description: Chemin de l’objet non valide
WSH Source : SWbemServicesEx
WMI>> Error context follows:
[WMI> creating SwbemLastError object]
WMI>> SwbemLastError CreateObject failed
WSH>> Error occurred
WSH Action : CreateObject
WSH Error nr : 80004005
WSH Description: [missing]
WSH Source : [missing]
c:\vbs>
Pour télécharger le source du script
wmi_printer_error.vbs,
cliquer ici.
Pour lire une étude détaillée du
script
wmi_printer_error.vbs et de son Error Handler, cliquer là.
[début]
V - JOURNALISATION
DES ERREURS EN ENVIRONNEMENT VBScript
Pour journaliser les erreurs d'un
script, nous allons tout naturellement modifier notre Error Handler
de façon appropriée.
Voici les lignes qui lui ont été
ajoutées ici et là :
Dim
strLogfile, strData, objFSO, outFile, i
Dim strLine(4)
Const ForAppending = 8
strLogfile = "c:\vbs\log\log.txt"
set objFSO = CreateObject("Scripting.FileSystemObject")
set outFile = objFSO.OpenTextFile(strLogfile, ForAppending, True)
for i =
0 to 4
strData = now & " - " & Wscript.ScriptName & " - " & strLine(i)
outFile.WriteLine(strData)
wscript.echo strLine(i)
next
outFile.Close
Voyons ce qu'elles signifient.
strLogfile
c'est la variable qui contient le
nom du fichier de log.
strData
c'est la variable qui contient la
ligne à écrire dans le fichier de log
objFSO
c'est la variable qui sert à
instancier l'objet File System
outFile
c'est la variable qui sert à
exécuter la méthode d'ouverture du fichier de log
i
c'est l'indice de boucle de
chargement d'une matrice de texte
strLine(4)
c'est une matrice de texte qui
contient les données à écrire dans le fichier de log
Const ForAppending = 8
Cette constante permet de
préciser à l'ouverture du fichier de log que l'on veut faire un Append
strLogfile = "c:\vbs\log\log.txt"
cette variable contient
maintenant la spécification complète du fichier de log
set
objFSO = CreateObject("Scripting.FileSystemObject")
c'est l'instanciation du File
System
set
outFile = objFSO.OpenTextFile(strLogfile, ForAppending, True)
c'est l'ouverture en mode Append
du fichier de log. L'indicateur booléen True signifie que si le fichier
n'existe pas il doit être créé.
for i = 0 to 4
strData = now & " - " & Wscript.ScriptName & " - " & strLine(i)
outFile.WriteLine(strData)
wscript.echo strLine(i)
next
Cette boucle crée une ligne de
données composée du groupe date/heure (GDH) de l'évènement, suivi du nom de
la procédure, suivi d'un texte informatif renseigné dans le Error Handler.
Ensuite on écrit dans le fichier de log et enfin on affiche un résumé des
données sur l'écran (sans le GDH et sans le nom du script).
outFile.Close
cette instruction ferme le
fichier de log afin d'éviter de le verrouiller si une autre procédure
souhaite y écrire en même temps.
Résultat :
Log.txt
03/11/2010 16:07:14 - WMI_printer_error_v2.vbs - WSH Action : GetObject
03/11/2010 16:07:14 - WMI_printer_error_v2.vbs - WSH Fatal error: 462
03/11/2010 16:07:14 - WMI_printer_error_v2.vbs - WSH Description: Le serveur
distant n'existe pas ou n'est pas disponible
03/11/2010 16:07:14 - WMI_printer_error_v2.vbs - WSH Source : Erreur
d'exécution Microsoft VBScript
03/11/2010 16:07:14 - WMI_printer_error_v2.vbs - Procedure terminated
abnormally.
03/11/2010 16:07:33 - WMI_printer_error_v2.vbs - WSH Action : GetPrinter
03/11/2010 16:07:33 - WMI_printer_error_v2.vbs - WSH Error nr : 80041002
03/11/2010 16:07:33 - WMI_printer_error_v2.vbs - WSH Description: Non trouvé
03/11/2010 16:07:33 - WMI_printer_error_v2.vbs - WSH Source :
SWbemServicesEx
03/11/2010 16:07:33 - WMI_printer_error_v2.vbs -
03/11/2010 16:08:01 - WMI_printer_error_v2.vbs - WSH Action : GetPrinter
03/11/2010 16:08:01 - WMI_printer_error_v2.vbs - WSH Error nr : 8004103A
03/11/2010 16:08:01 - WMI_printer_error_v2.vbs - WSH Description: Chemin de
l’objet non valide
03/11/2010 16:08:01 - WMI_printer_error_v2.vbs - WSH Source :
SWbemServicesEx
03/11/2010 16:08:01 - WMI_printer_error_v2.vbs -
03/11/2010 16:08:01 - WMI_printer_error_v2.vbs - WSH Action : CreateObject
03/11/2010 16:08:01 - WMI_printer_error_v2.vbs - WSH Fatal error: 80004005
03/11/2010 16:08:01 - WMI_printer_error_v2.vbs - WSH Description: [text
missing]
03/11/2010 16:08:01 - WMI_printer_error_v2.vbs - WSH Source : [text missing]
03/11/2010 16:08:01 - WMI_printer_error_v2.vbs - Procedure terminated
abnormally
Pour télécharger le source du
script errmgt.vbs,
cliquer ici (clic droit > enregistrer la cible du lien
sous)
[début]
accueil | console |
VBScript | PowerShell
|
documentation |
formation |
trucs et astuces |
exemples |
glossaire
|