Réexécuter un script .bat après redémarrage

Il arrive parfois que l’on doive redémarrer Windows après une installation ou une configuration du système. Lorsque cette installation ou configuration se fait automatiquement dans le cadre d’un fichier .bat, le redémarrage provoque évidemment l’interruption du script… qui doit donc être relancé au redémarrage, et qui doit détecter où en est l’installation. Pour éviter ce genre de problèmes, bien souvent, les commandes sont découpées en plusieurs fichiers .bat qui doivent être exécutés l’un après l’autre.

Il est cependant possible de gérer le redémarrage du système avec relance automatique du script au redémarrage et reprise de l’installation ou de la configuration à la bonne étape.

Techniquement, il faut faire appel à la clé suivante de la base de registre :

[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunOnce]

Et y insérer une nouvelle valeur chaîne avec ces paramètres :

Nom de la valeur : le nom de votre script, extension comprise (exemple : test.bat)
Données de la valeur : le chemin complet vers votre script (exemple : C:\scripts\test.bat)

La clé RunOnce est en fait une variante de la clé Run (qui contient des exécutables lancés à chaque démarrage), à la différence près que RunOnce est vidée après chaque exécution.

Pour reprendre l’exécution à la bonne étape, avant le redémarrage, le plus simple est peut-être de créer un fichier placé dans le dossier temporaire de l’utilisateur (désigné par la variable d’environnement %TEMP%). A chaque lancement, le script vérifie l’existence de ce fichier pour savoir quelle étape lancer. Une fois cette vérification faite, il faut que le script le supprime afin de ne pas se tromper d’étape à la prochaine exécution.

La principale difficulté est l’insertion dans la clé RunOnce. Récupérer le nom du fichier .bat, son chemin, et… « double antislasher » le chemin, c’est à dire remplacer :

C:\scripts\test.bat

par :

C:\\scripts\\test.bat

Pas si évident que cela… La solution :

@echo "%~nx0"="%CD:\=\\%\\%~nx0"

Autant dire qu’on ne tombe pas dessus par hasard. Voici un exemple complet, que vous pouvez utiliser, modifier… au gré de vos envies (et de vos besoins !) :

@echo off
 
REM --------------------------------------------------------------------
REM
REM Reexecuter un script .bat apres redemarrage
REM
REM --------------------------------------------------------------------
 
if exist %TEMP%\TESTBAT goto etape2
if not exist %TEMP%\TESTBAT goto etape1
 
:etape1
 
echo.
echo Reexecuter un script .bat apres redemarrage - Etape 1/2
echo --------------------------------------------------------------------
echo.
echo Veuillez indiquer quelques informations pour tester le script...
echo.
set /p id=identifiant bidon :
set /p mdp=Mot de passe bidon :
echo.
echo %id%>%TEMP%\TESTBAT
echo %mdp%>>%TEMP%\TESTBAT
 
echo Modification de la base de registre...
echo.
 
(
@echo Windows Registry Editor Version 5.00
@echo/
@echo [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunOnce]
@echo "%~nx0"="%CD:\=\\%\\%~nx0"
)>%TEMP%\TESTBAT.reg
 
regedit /s %TEMP%\TESTBAT.reg
del /q %TEMP%\TESTBAT.reg
 
cls
echo.
echo Reexecuter un script .bat apres redemarrage - Etape 1/2
echo --------------------------------------------------------------------
echo.
echo Les donnees ont ete enregistrees et seront affichees au redemarrage.
echo.
echo Testons a present le redemarrage du systeme
echo pour verifier que le script se relance bien.
echo.
 
set /p choix=Voulez-vous redemarrer immediatement (o/n) ?
if %choix%==o goto oui
if %choix%==n goto non
 
:oui
shutdown -r -t 0 & goto fin
 
:non
echo.
echo.
echo Votre systeme ne sera pas redemarre.
echo.
echo La suite au prochain demarrage de votre systeme.
echo.
pause
exit
 
:fin
exit
 
:etape2
 
echo.
echo Reexecuter un script .bat apres redemarrage - Etape 1/2
echo --------------------------------------------------------------------
echo.
 
for /f "delims=" %%a in ('type %TEMP%\TESTBAT') do (
if not defined id set id=%%a
)
for /f "delims=" %%a in ('type %TEMP%\TESTBAT') do set mdp=%%a
 
del /q %TEMP%\TESTBAT
 
echo Affichage des donnees precedemment demandees...
echo.
echo Le login bidon est : %id%
echo Le mot de passe bidon est : %mdp%
echo.
echo Le test est termine. Si vous redemarrez, rien ne se lancera...
echo.
pause
exit


Commentaires (11)

Snosky17 mars 2010 à 13 h 29 min

Bonjour je voudrai faire ceci mai pour l’installation d’un logiciel qui se fait en 2 partis donc une après un redémarrage mais quant le batch s’execute au moment dans venir registre Windows il dit « impossible de trouver C:\DOCUME~1~\oncfs\LOCALS~1~\Temp\monlogicielle.reg pourrait tu m’aider s’il te plaît

Snosky17 mars 2010 à 15 h 44 min

C’est bon j’ai résolu mon problème mais j’en ai un nouveau ^^ au redémarrage le batch se relance mais à partir du début et pas à l’étape 2.

Nicolas17 mars 2010 à 15 h 55 min

Bonjour !

Au redémarrage, vérifie que le fichier %TEMP%\TESTBAT existe bien (le passage à l’étape 2 est déclenché par l’existence de ce fichier), en tapant par exemple « notepad %TEMP%\TESTBAT » dans un invite de commandes. Si le fichier n’existe pas, c’est qu’il y a un souci à la création.

Snosky17 mars 2010 à 16 h 51 min

ok je te tien au courant.

Snosky18 mars 2010 à 10 h 11 min

Le fichier n’existe pas au redémarrage.

Voici mon batch dit moi si il ya a une erreur :

http://pastebin.com/C6vgSbfV

Nicolas18 mars 2010 à 13 h 24 min

Je me suis permis de copier/coller ton code sur PasteBin pour alléger cette page.

Il y a effectivement une erreur : à l’étape 1, aucun fichier %TEMP%\MacAfee n’est créé. Si tu regardes ma solution, des données sont inscrites dans %TEMP%\TESTBAT à l’étape 1, juste après avoir demandé à l’utilisateur des informations « bidon ». Du coup, dans ton exemple, ce fichier n’existe pas au moment de redémarrer et il est donc logique que le script reprenne à l’étape 1.

Snosky18 mars 2010 à 13 h 54 min

Et il n’y a pas moyen de modifie pour que cela fonctionne ?

Snosky18 mars 2010 à 14 h 20 min

C’est bon j’ai reussi j’ai juste inclu une variante comme toi (ligne 23):

http://pastebin.com/dcyEXMGu

Merci de ton aide.

PS : J’ai mi un bail de 1 jour sur pastebin donc si tu n’a pas le temps de le regarder envoie moi un mail. Et je tien aussi a dire que je n’ai que 17 ans et tout sa est pour impressionner mon maitre de stage xD

Nicolas18 mars 2010 à 15 h 26 min

C’est OK.

Par contre, les boucles for sont inutiles dans ton étape 2 (lignes 62 à 65) vu que tu ne récupères aucune donnée dans le fichier %TEMP%\MacAfee (dans mon exemple, je m’en servais pour réafficher les valeurs saisies par l’utilisateur).

sebastien28 mars 2011 à 14 h 47 min

bonjour,

comment faire la même chose mais sur plusieurs redemarrage? car sur ce modele au second redemarrage le script ne se relance pas (en ajoutant une etape3 bien entendu..)

Nicolas28 mars 2011 à 18 h 04 min

Bonjour,

Le redémarrage se fait grâce à la modification de la base de registre. Pour ajouter un nouveau redémarrage, il faut répéter une nouvelle fois cette étape (création du fichier .reg, insertion dans la base de registre et suppression du fichier .reg), étant donné que RunOnce se purge après avoir exécuté les commandes s’y trouvant.

Il serait peut-être intéressant de modifier le fichier TESTBAT servant à déterminer l’étape à lancer, de façon à lire à chaque fois son contenu et en déroulant le script en fonction (fichier absent : étape 1, contenant ’1′ : lancement de l’étape 2, contenant ’2′ : lancement de l’étape 3).

Laisser un commentaire

Votre commentaire