# Shared preparation/upgrade mutex. ASCII for Windows PowerShell 5.1. function Enter-ArtemisInstallationLock { param([string]$ProjectRoot) $normalized = [IO.Path]::GetFullPath($ProjectRoot).TrimEnd('\').ToLowerInvariant() $hash = [Security.Cryptography.SHA256]::Create() try { $digest = [BitConverter]::ToString($hash.ComputeHash([Text.Encoding]::UTF8.GetBytes($normalized))).Replace('-', '') } finally { $hash.Dispose() } $mutex = New-Object Threading.Mutex($false, "Local\ArtemisInstallation-$digest") try { try { $entered = $mutex.WaitOne(0) } catch [Threading.AbandonedMutexException] { $entered = $true } if (-not $entered) { throw 'Another startup preparation or upgrade is running. Please wait and retry.' } return $mutex } catch { $mutex.Dispose(); throw } } function Exit-ArtemisInstallationLock { param($Mutex) if ($null -ne $Mutex) { $Mutex.ReleaseMutex(); $Mutex.Dispose() } }