install.ps1 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. # ==============================================================================
  2. # lf_mri_platform -- One-time installation script
  3. # Run as: .\install.ps1
  4. # Requires: Windows 10/11, PowerShell 5.1+, internet access
  5. # ==============================================================================
  6. param(
  7. [string]$PythonExe = "python"
  8. )
  9. $ErrorActionPreference = "Stop"
  10. $Root = $PSScriptRoot
  11. $GuiDir = Join-Path $Root "apps\gui"
  12. $LibsDir = Join-Path $Root "libs\lf-scanner"
  13. function Write-Step($msg) { Write-Host "`n==> $msg" -ForegroundColor Cyan }
  14. function Write-OK($msg) { Write-Host " [OK] $msg" -ForegroundColor Green }
  15. function Write-Warn($msg) { Write-Host " [!!] $msg" -ForegroundColor Yellow }
  16. function Write-Fail($msg) { Write-Host " [FAIL] $msg" -ForegroundColor Red; exit 1 }
  17. # -- 1. Check prerequisites ----------------------------------------------------
  18. Write-Step "Checking prerequisites"
  19. try {
  20. $pyVer = & $PythonExe --version 2>&1
  21. if ($pyVer -match "3\.(1[0-9]|[0-9]+)") { Write-OK "Python: $pyVer" }
  22. else { Write-Fail "Python 3.10+ required, found: $pyVer" }
  23. } catch { Write-Fail "Python not found. Install from https://python.org (add to PATH)" }
  24. try {
  25. $dockerVer = & docker --version 2>&1
  26. Write-OK "Docker: $dockerVer"
  27. } catch {
  28. Write-Warn "Docker not found -- backend services will not start without it."
  29. Write-Warn "Install Docker Desktop: https://www.docker.com/products/docker-desktop/"
  30. }
  31. try {
  32. $composeVer = & docker compose version 2>&1
  33. Write-OK "Docker Compose: $composeVer"
  34. } catch { Write-Warn "Docker Compose not found (included in Docker Desktop >= 3.0)" }
  35. # -- 2. Create Python virtual environment for the GUI -------------------------
  36. Write-Step "Creating Python virtual environment for GUI"
  37. $venvPath = Join-Path $GuiDir ".venv"
  38. if (-not (Test-Path $GuiDir)) { Write-Fail "GUI directory not found: $GuiDir" }
  39. if (Test-Path $venvPath) {
  40. Write-Warn "Venv already exists at $venvPath -- skipping creation"
  41. } else {
  42. & $PythonExe -m venv $venvPath
  43. Write-OK "Created venv at $venvPath"
  44. }
  45. $pip = Join-Path $venvPath "Scripts\pip.exe"
  46. # -- 3. Install GUI dependencies ----------------------------------------------
  47. Write-Step "Installing GUI dependencies"
  48. $guiReqs = Join-Path $GuiDir "requirements.txt"
  49. if (Test-Path $guiReqs) {
  50. & $pip install -r $guiReqs --quiet
  51. Write-OK "GUI requirements installed"
  52. }
  53. # Install lf-scanner as an editable package
  54. $lfScannerPyproject = Join-Path $LibsDir "pyproject.toml"
  55. $lfScannerSetup = Join-Path $LibsDir "setup.py"
  56. if ((Test-Path $lfScannerPyproject) -or (Test-Path $lfScannerSetup)) {
  57. & $pip install -e $LibsDir --quiet
  58. Write-OK "lf-scanner installed (editable)"
  59. } else {
  60. Write-Warn "lf-scanner has no pyproject.toml/setup.py -- adding to PYTHONPATH only"
  61. }
  62. # -- 4. Copy .env for Docker services -----------------------------------------
  63. Write-Step "Setting up Docker environment config"
  64. $envFile = Join-Path $Root ".env"
  65. $envExample = Join-Path $Root ".env.example"
  66. if (-not (Test-Path $envFile)) {
  67. Copy-Item $envExample $envFile
  68. Write-OK ".env created from .env.example"
  69. } else {
  70. Write-Warn ".env already exists -- not overwriting"
  71. }
  72. # -- 5. Create desktop shortcuts ----------------------------------------------
  73. Write-Step "Creating desktop shortcuts"
  74. $desktopPath = [Environment]::GetFolderPath("Desktop")
  75. $pythonExePath = Join-Path $venvPath "Scripts\python.exe"
  76. $appScript = Join-Path $GuiDir "app.py"
  77. $wsh = New-Object -ComObject WScript.Shell
  78. # GUI only
  79. $sc = $wsh.CreateShortcut("$desktopPath\LF-MRI GUI.lnk")
  80. $sc.TargetPath = $pythonExePath
  81. $sc.Arguments = "`"$appScript`""
  82. $sc.WorkingDirectory = $Root
  83. $sc.Description = "LF-MRI System GUI"
  84. $sc.Save()
  85. Write-OK "Shortcut: 'LF-MRI GUI.lnk' on Desktop"
  86. # Start all
  87. $scAll = $wsh.CreateShortcut("$desktopPath\LF-MRI Start All.lnk")
  88. $scAll.TargetPath = "powershell.exe"
  89. $scAll.Arguments = "-ExecutionPolicy Bypass -File `"$Root\start.ps1`""
  90. $scAll.WorkingDirectory = $Root
  91. $scAll.Description = "Start LF-MRI services + GUI"
  92. $scAll.Save()
  93. Write-OK "Shortcut: 'LF-MRI Start All.lnk' on Desktop"
  94. # -- 6. Summary ---------------------------------------------------------------
  95. Write-Host ""
  96. Write-Host "============================================================" -ForegroundColor Green
  97. Write-Host " Installation complete!" -ForegroundColor Green
  98. Write-Host "============================================================" -ForegroundColor Green
  99. Write-Host ""
  100. Write-Host " Next steps:"
  101. Write-Host " 1. Start all services + GUI: .\start.ps1"
  102. Write-Host " 2. GUI only (no services): .\start.ps1 -GuiOnly"
  103. Write-Host " 3. Hardware mode: .\start.ps1 -Mode real"
  104. Write-Host " 4. Stop services: .\stop.ps1"
  105. Write-Host ""
  106. Write-Host " Config: edit .env to change ports or switch mode (plug/real)"
  107. Write-Host ""