Question [Astuce]Interdire l'exécution multiple d'1 script

Plus d'informations
il y a 16 ans 6 mois #5328 par Laurent Dardenne
Voici un script, basé sur des mutex nommés, qui empêche d'exécuter au même moment deux fois le même script sur une même machine.
[code:1]
#
Déclarations
$script:isMutexExist =$true

$sbFinallyMutex={
#Supprime l'objet référençant un mutex système
$Mutex.Close()
$Mutex=$null
}

$MutexName=\"ScriptPSUnique\"

.{
trap [System.Threading.WaitHandleCannotBeOpenedException]
{
Write-Debug \"Le Mutex '$MutexName' n'est pas en cours d'utilisation.\";
$script:isMutexExist =$false
Continue
}#trap
#est-ce que le mutex a été crée
$Mutex= [System.Threading.Mutex]::OpenExisting($MutexName)
}

#
Tests
#Si le mutex existe déjà on quitte le script
if ($script:isMutexExist)
{
Write-Debug \"Le Mutex '$MutexName' est en cours d'utilisation.\";
&$sbFinallyMutex
throw \"Script $($MyInvocation.MyCommand) en cours d’exécution.\"
}

[ref]$createdNew = $false
#Sinon on le crée et on l'acquiert
$Mutex=New-Object System.Threading.Mutex $true, $MutexName,$createdNew
if ($createdNew.Value -eq $false)
{
#On veut vraiment s’assurer que ce mutex
#appartienne au thread courant.
#Un autre thread peut acquérir ce mutex libre avant ce script
Write-host \"Le mutex nommé '$MutexName' existe déjà, il n'appartient pas à ce thread.\";
&$sbFinallyMutex
throw \"Script $($MyInvocation.MyCommand) en cours d’exécution.\"
}

#
Corps du script
.{
trap
{
Write-Debug \"Exception : Libération du Mutex .\";
$Mutex.ReleaseMutex()
&$sbFinallyMutex
Throw $_ #On redéclenche l'exception
}


#<- Placer ici vos instructions
Write-host {\"Suite du traitement. Saisir une touche pour libérer le mutex.\"}
pause
throw \"Test d'exception.\"
#->fin du script

#libére le mutex
$Mutex.ReleaseMutex()
&$sbFinallyMutex
}
[/code:1]
Pour le tester placez ces lignes dans un script puis exécutez le dans 2 sessions PowerShell.
La fonction pause

Utilisez $DebugPreference=\&quot;Continue\&quot;,<br><br>Message édité par: Laurent Dardenne, à: 22/09/09 20:07

Tutoriels PowerShell

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 16 ans 5 mois #5344 par Laurent Dardenne
Une petite correction, l'appel suivant n'est pas nécessaire:
[code:1]
#Acquiert le mutex
$Mutex.WaitOne()
[/code:1]
J'ai mis à jour le script du premier post.

Tutoriels PowerShell

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 16 ans 5 mois #5345 par Laurent Dardenne
Un second script dans la lignée du premier.
Cette fois-ci on autorise l'exécution d'autres scripts utilisant le même mutex, mais on attend la fin du premier script avant de poursuivre l'exécution des autres.On exécute un script à la fois.

Ici le scénario est : tout le monde accède à une même ressource mais pas en même temps.

Chaque script utilisant cette structure, basée sur un mutex, est donc mis dans 'une file d'attente'. L'ordre d'exécution est donc celui d'une FIFO (First In, First Out).
[code:1]
#
Déclarations
$script:isMutexExist =$true
$MutexName=\&quot;QueuingScript\&quot;
[ref]$createdNew = $false

$sbFinallyMutex={
#Supprime l'objet référençant un mutex système
$Mutex.Close()
$Mutex=$null
}

trap
{
Write-Debug \&quot;Exception : Libération du Mutex .\&quot;;
$Mutex.ReleaseMutex()
&amp;$sbFinallyMutex
Throw $_ #On redéclenche l'exception
}

.{
trap [System.Threading.WaitHandleCannotBeOpenedException]
{
Write-Debug \&quot;Le Mutex '$MutexName' n'est pas en cours d'utilisation.\&quot;;
$script:isMutexExist =$false
Continue
}#trap

#Est-ce que le mutex a été créé ?
$Mutex= [System.Threading.Mutex]::OpenExisting($MutexName)
if ($script:isMutexExist)
{
Write-Debug \&quot;Le Mutex '$MutexName' est en cours d'utilisation.\&quot;
Write-Debug \&quot;On attend sa libération.\&quot;
[void]$Mutex.WaitOne()
Write-Debug \&quot;On acquiert le mutex.\&quot;
}
}

#
Tests
#Si le mutex existe déjà on attend
if (!$script:isMutexExist)
{
#Sinon on le crée et on l'acquiert
$Mutex=New-Object System.Threading.Mutex $true, $MutexName,$createdNew
if ($createdNew.Value -eq $false)
{
#On veut vraiment s’assurer que ce mutex
#appartienne au thread courant.
#Un autre thread peut acquérir ce mutex libre avant ce script
Write-host \&quot;Le mutex nommé '$MutexName' existe déjà, il n'appartient pas à ce thread.\&quot;
Write-Debug \&quot;On attend sa libération.\&quot;
[void]$Mutex.WaitOne()
Write-Debug \&quot;On acquiert le mutex.\&quot;
}
else { Write-Debug \&quot;On acquiert le mutex dés sa création.\&quot;}
}


#
Corps du script

#&lt;- Placer ici vos instructions
Write-host {\&quot;Suite du traitement. Saisir une touche pour libérer le mutex.\&quot;}
pause
throw \&quot;Test d'exception.\&quot;
#-&gt;fin du script

#libére le mutex
$Mutex.ReleaseMutex()
&amp;$sbFinallyMutex
[/code:1]
Pour le tester placez ces lignes dans un script puis exécutez le dans 2..n sessions PowerShell.

Utilisez $DebugPreference=\&quot;Continue\&quot;.

Message édité par: Laurent Dardenne, à: 22/09/09 20:08<br><br>Message édité par: Laurent Dardenne, à: 22/09/09 20:09

Tutoriels PowerShell

Connexion ou Créer un compte pour participer à la conversation.

Temps de génération de la page : 0.048 secondes
Propulsé par Kunena