@@ -63,15 +63,32 @@ Component.prototype.createOperations = function() {
6363 // its QtWebEngineProcess helper keeps e.g. resources/icudtl.dat
6464 // memory-mapped) or carry a read-only attribute; either aborts
6565 // extraction with "Can't unlink already-existing object: Permission
66- // denied". Stop processes running from the target dir and clear
67- // attributes before the archives are extracted.
66+ // denied". A fixed sleep after Stop-Process is a guess and does not
67+ // cover a lock held by something outside the target dir (antivirus
68+ // real-time scan, indexer, etc.), so this actually waits for our own
69+ // processes to exit and then verifies every existing file can be
70+ // opened exclusively before the archives are extracted, retrying
71+ // for a few seconds if something still holds a handle.
6872 var unlockScript =
6973 "$targetDir = " + psLiteral ( toWindowsPath ( targetDirRaw ) ) + "; " +
7074 "try { " +
7175 " if (Test-Path $targetDir) { " +
72- " Get-Process -ErrorAction SilentlyContinue | Where-Object { $_.Path -and $_.Path.StartsWith(($targetDir.TrimEnd('\\') + '\\'), [StringComparison]::OrdinalIgnoreCase) } | Stop-Process -Force -ErrorAction SilentlyContinue; " +
73- " Start-Sleep -Milliseconds 800; " +
74- " attrib.exe -R ($targetDir.TrimEnd('\\') + '\\*') /S /D; " +
76+ " $prefix = $targetDir.TrimEnd('\\') + '\\'; " +
77+ " $procs = Get-Process -ErrorAction SilentlyContinue | Where-Object { $_.Path -and $_.Path.StartsWith($prefix, [StringComparison]::OrdinalIgnoreCase) }; " +
78+ " if ($procs) { " +
79+ " $procs | Stop-Process -Force -ErrorAction SilentlyContinue; " +
80+ " foreach ($p in $procs) { try { if (-not $p.HasExited) { $p.WaitForExit(5000) | Out-Null } } catch {} } " +
81+ " } " +
82+ " attrib.exe -R ($prefix + '*') /S /D; " +
83+ " $deadline = (Get-Date).AddSeconds(6); " +
84+ " do { " +
85+ " $locked = $false; " +
86+ " Get-ChildItem -Path $targetDir -Recurse -File -ErrorAction SilentlyContinue | ForEach-Object { " +
87+ " try { ([System.IO.File]::Open($_.FullName, 'Open', 'ReadWrite', 'None')).Close() } catch { $locked = $true } " +
88+ " }; " +
89+ " if (-not $locked) { break }; " +
90+ " Start-Sleep -Milliseconds 300; " +
91+ " } while ((Get-Date) -lt $deadline); " +
7592 " } " +
7693 "} catch {}; exit 0" ;
7794
0 commit comments