diff --git a/build.ps1 b/build.ps1 index 731cc8e..1630b6d 100644 --- a/build.ps1 +++ b/build.ps1 @@ -1,6 +1,28 @@ # PowerShell Build Script for S7 Streamer & Logger # Compatible with PowerShell Core and Windows PowerShell +# Function to safely handle Python process management +function Show-PythonProcessDetails { + param($processes) + + Write-Host "`nDetailed Python process information:" -ForegroundColor Cyan + for ($i = 0; $i -lt $processes.Count; $i++) { + $proc = $processes[$i] + $commandLine = "" + try { + $commandLine = (Get-WmiObject Win32_Process -Filter "ProcessId = $($proc.Id)").CommandLine + } catch { + $commandLine = "Unable to retrieve command line" + } + + Write-Host "[$($i+1)] PID: $($proc.Id) - $($proc.ProcessName)" -ForegroundColor White + Write-Host " Window: $($proc.MainWindowTitle)" -ForegroundColor Gray + Write-Host " Command: $commandLine" -ForegroundColor Gray + Write-Host " Start Time: $($proc.StartTime)" -ForegroundColor Gray + Write-Host "" + } +} + Write-Host "Starting build process..." -ForegroundColor Green # Step 1: Build Frontend @@ -38,6 +60,77 @@ try { Write-Host "Build completed successfully!" -ForegroundColor Green Write-Host "Results available in: dist/main/" -ForegroundColor Cyan + + # Wait for PyInstaller to fully release file handles + Write-Host "Waiting for file handles to be released..." -ForegroundColor Yellow + Start-Sleep -Seconds 3 + + # Check for Python processes that might hold file handles + $pythonProcesses = Get-Process -Name "python*" -ErrorAction SilentlyContinue | Where-Object { $_.ProcessName -match "python" } + + if ($pythonProcesses.Count -gt 0) { + Write-Host "`nFound $($pythonProcesses.Count) Python process(es):" -ForegroundColor Yellow + $pythonProcesses | ForEach-Object { + Write-Host " PID: $($_.Id) - $($_.ProcessName) - $($_.MainWindowTitle)" -ForegroundColor Gray + } + + Write-Host "`nSome Python processes might be holding file handles that could interfere with compression." -ForegroundColor Yellow + Write-Host "Options:" -ForegroundColor Cyan + Write-Host " [y] Terminate ALL Python processes" -ForegroundColor White + Write-Host " [d] Show DETAILED information and select specific processes" -ForegroundColor White + Write-Host " [n] Keep all processes running (default)" -ForegroundColor White + + $response = Read-Host "Choose an option (y/d/N)" + + if ($response -eq 'y' -or $response -eq 'Y') { + Write-Host "Terminating ALL Python processes..." -ForegroundColor Yellow + try { + $pythonProcesses | Stop-Process -Force -ErrorAction SilentlyContinue + Write-Host "All Python processes terminated." -ForegroundColor Green + } catch { + Write-Host "Warning: Some processes could not be terminated: $_" -ForegroundColor Yellow + } + Start-Sleep -Seconds 2 + + } elseif ($response -eq 'd' -or $response -eq 'D') { + Show-PythonProcessDetails -processes $pythonProcesses + + Write-Host "Enter the numbers of processes to terminate (e.g., '1,3,5' or 'all' or 'none'):" -ForegroundColor Cyan + $selection = Read-Host "Selection" + + if ($selection -eq 'all') { + Write-Host "Terminating ALL Python processes..." -ForegroundColor Yellow + $pythonProcesses | Stop-Process -Force -ErrorAction SilentlyContinue + } elseif ($selection -ne 'none' -and $selection -ne '') { + $indices = $selection.Split(',') | ForEach-Object { $_.Trim() } + Write-Host "Terminating selected processes..." -ForegroundColor Yellow + + foreach ($index in $indices) { + try { + $processIndex = [int]$index - 1 + if ($processIndex -ge 0 -and $processIndex -lt $pythonProcesses.Count) { + $proc = $pythonProcesses[$processIndex] + Stop-Process -Id $proc.Id -Force -ErrorAction SilentlyContinue + Write-Host " Terminated PID $($proc.Id)" -ForegroundColor Green + } else { + Write-Host " Invalid index: $index" -ForegroundColor Red + } + } catch { + Write-Host " Could not terminate process $index: $_" -ForegroundColor Red + } + } + } else { + Write-Host "No processes will be terminated." -ForegroundColor Yellow + } + Start-Sleep -Seconds 2 + + } else { + Write-Host "Keeping all Python processes running. If compression fails, you may need to close them manually." -ForegroundColor Yellow + } + } else { + Write-Host "No Python processes found that could interfere with build." -ForegroundColor Green + } + } catch { Write-Host "PyInstaller build failed: $_" -ForegroundColor Red exit 1 @@ -77,7 +170,67 @@ try { if (-not $sevenZipFound) { Write-Host "Using PowerShell built-in compression..." -ForegroundColor Cyan $tempZip = ".\$zipName" - Compress-Archive -Path ".\dist\main\*" -DestinationPath $tempZip -Force + + # Retry compression up to 3 times with delays + $retryCount = 0 + $maxRetries = 3 + $compressionSuccess = $false + + while ($retryCount -lt $maxRetries -and -not $compressionSuccess) { + try { + if ($retryCount -gt 0) { + Write-Host "Retrying compression (attempt $($retryCount + 1)/$maxRetries)..." -ForegroundColor Yellow + Start-Sleep -Seconds 5 + } + + # Force garbage collection to release any lingering file handles + [System.GC]::Collect() + [System.GC]::WaitForPendingFinalizers() + + Compress-Archive -Path ".\dist\main\*" -DestinationPath $tempZip -Force + $compressionSuccess = $true + + } catch { + $retryCount++ + Write-Host "Compression attempt $retryCount failed: $_" -ForegroundColor Yellow + + if ($retryCount -eq $maxRetries) { + # Final attempt: try creating a copy first, then compress + Write-Host "Trying alternative method: copy then compress..." -ForegroundColor Yellow + $tempDir = ".\temp_build_$timestamp" + + if (Test-Path $tempDir) { + Remove-Item -Recurse -Force $tempDir + } + + # Copy files to temporary directory + Copy-Item -Path ".\dist\main" -Destination $tempDir -Recurse -Force + + # Wait a moment + Start-Sleep -Seconds 2 + + # Try to compress the copy + try { + Compress-Archive -Path "$tempDir\*" -DestinationPath $tempZip -Force + $compressionSuccess = $true + + # Clean up temp directory + Remove-Item -Recurse -Force $tempDir + + } catch { + # Clean up temp directory + if (Test-Path $tempDir) { + Remove-Item -Recurse -Force $tempDir + } + throw $_ + } + } + + if (-not $compressionSuccess) { + throw $_ + } + } + } # Move to destination $zipFullPath = Join-Path $destinationPath $zipName @@ -91,6 +244,20 @@ try { $fileSize = (Get-Item $zipFullPath).Length / 1MB Write-Host "Archive size: $([math]::Round($fileSize, 2)) MB" -ForegroundColor Gray + # Open Windows Explorer in the destination directory + Write-Host "Opening destination folder..." -ForegroundColor Yellow + try { + # Use Windows Explorer to open the destination directory and select the ZIP file + explorer.exe /select,"$zipFullPath" + } catch { + # Fallback: just open the directory + try { + explorer.exe "$destinationPath" + } catch { + Write-Host "Could not open Explorer automatically. File location: $zipFullPath" -ForegroundColor Yellow + } + } + } catch { Write-Host "Compression failed: $_" -ForegroundColor Red exit 1