Skip to content

Commit f58e2a6

Browse files
committed
Add Windows automatic installer and python -m fallback
Made-with: Cursor
1 parent 355dfd5 commit f58e2a6

3 files changed

Lines changed: 201 additions & 1 deletion

File tree

README.md

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,22 @@ It registers URI handlers for other slicers (PrusaSlicer, OrcaSlicer, Cura, and
1212

1313
## Installation
1414

15+
### Windows (automatic)
16+
17+
Open PowerShell and run:
18+
19+
```powershell
20+
powershell -ExecutionPolicy Bypass -c "iwr -useb https://raw.githubusercontent.com/mbv06/slicer-uri-bridge/main/install-windows.ps1 | iex"
21+
```
22+
23+
The installer creates a private virtual environment in `%LOCALAPPDATA%\slicer-uri-bridge`, installs or upgrades the package there, adds the Scripts directory to the user `PATH`, initializes config if needed, and registers URI handlers.
24+
25+
After installation, open a new terminal window if the command is not found, then test the registered handler by opening a known Benchy model URI:
26+
27+
```powershell
28+
slicer-uri-bridge test
29+
```
30+
1531
### macOS (automatic)
1632

1733
Run the installer:
@@ -131,7 +147,7 @@ slicer-uri-bridge config-path
131147

132148
Log files in that directory record each handler invocation and can help diagnose download failures, URI parsing issues, or slicer launch problems.
133149

134-
If the `slicer-uri-bridge` command is not found after installation, make sure the Python scripts directory is on your `PATH`. On macOS with the automatic installer, open a new Terminal window. On Windows, ensure the `Add python.exe to PATH` option was enabled during Python installation.
150+
If the `slicer-uri-bridge` command is not found after installation, make sure the Python scripts directory is on your `PATH`. On macOS with the automatic installer, open a new Terminal window. On Windows, ensure the `Add python.exe to PATH` option was enabled during Python installation, or use the automatic installer above. As a fallback, you can always run `python -m slicer_uri_bridge` instead of `slicer-uri-bridge`.
135151

136152
If URI links do not open after registration, verify the current handler status:
137153

install-windows.ps1

Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
#Requires -Version 5.1
2+
<#
3+
.SYNOPSIS
4+
Slicer URI Bridge Windows installer.
5+
6+
.DESCRIPTION
7+
1. Finds Python 3.11+
8+
2. Creates a private virtual environment
9+
3. Installs / upgrades Slicer URI Bridge into that environment
10+
4. Adds the environment Scripts directory to the user PATH
11+
5. Creates config if missing
12+
6. Registers URI handlers
13+
7. Shows how to test the registered handler
14+
15+
To update later, run this installer again.
16+
17+
.EXAMPLE
18+
powershell -ExecutionPolicy Bypass -File install-windows.ps1
19+
#>
20+
21+
Set-StrictMode -Version Latest
22+
$ErrorActionPreference = 'Stop'
23+
24+
$ProjectSpec = 'https://github.com/mbv06/slicer-uri-bridge/archive/refs/heads/main.zip'
25+
$AppHome = Join-Path $env:LOCALAPPDATA 'slicer-uri-bridge'
26+
$VenvDir = Join-Path $AppHome 'venv'
27+
$ScriptsDir = Join-Path $VenvDir 'Scripts'
28+
$BridgeExe = Join-Path $ScriptsDir 'slicer-uri-bridge.exe'
29+
$MinMajor = 3
30+
$MinMinor = 11
31+
32+
function Log($Message) {
33+
Write-Host "`n==> $Message" -ForegroundColor Cyan
34+
}
35+
36+
function Die($Message) {
37+
Write-Host "Error: $Message" -ForegroundColor Red
38+
exit 1
39+
}
40+
41+
function Test-PythonCompatible($PythonPath) {
42+
try {
43+
$version = & $PythonPath -c 'import sys; print(f"{sys.version_info.major}.{sys.version_info.minor}")' 2>$null
44+
if (-not $version) { return $false }
45+
$parts = $version.Split('.')
46+
$major = [int]$parts[0]
47+
$minor = [int]$parts[1]
48+
return ($major -gt $MinMajor) -or ($major -eq $MinMajor -and $minor -ge $MinMinor)
49+
}
50+
catch {
51+
return $false
52+
}
53+
}
54+
55+
function Find-Python {
56+
$candidates = @(
57+
'python3.14', 'python3.13', 'python3.12', 'python3.11',
58+
'python3', 'python', 'py'
59+
)
60+
61+
foreach ($candidate in $candidates) {
62+
$path = Get-Command $candidate -ErrorAction SilentlyContinue |
63+
Select-Object -ExpandProperty Source -ErrorAction SilentlyContinue
64+
if ($path -and (Test-PythonCompatible $path)) {
65+
return $path
66+
}
67+
}
68+
69+
# Try the py launcher with version flags
70+
$pyLauncher = Get-Command 'py' -ErrorAction SilentlyContinue |
71+
Select-Object -ExpandProperty Source -ErrorAction SilentlyContinue
72+
if ($pyLauncher) {
73+
foreach ($ver in @('-3.14', '-3.13', '-3.12', '-3.11')) {
74+
try {
75+
$check = & $pyLauncher $ver -c 'import sys; print(sys.executable)' 2>$null
76+
if ($check -and (Test-PythonCompatible $check)) {
77+
return $check
78+
}
79+
}
80+
catch {}
81+
}
82+
}
83+
84+
return $null
85+
}
86+
87+
function Add-ToUserPath($Directory) {
88+
$userPath = [Environment]::GetEnvironmentVariable('Path', 'User')
89+
if (-not $userPath) { $userPath = '' }
90+
91+
$entries = $userPath.Split(';', [StringSplitOptions]::RemoveEmptyEntries)
92+
$normalized = $entries | ForEach-Object { $_.TrimEnd('\') }
93+
$target = $Directory.TrimEnd('\')
94+
95+
if ($normalized -contains $target) {
96+
return $false
97+
}
98+
99+
$newPath = if ($userPath) { "$userPath;$Directory" } else { $Directory }
100+
[Environment]::SetEnvironmentVariable('Path', $newPath, 'User')
101+
102+
# Update the current session so the command is immediately available
103+
if ($env:Path -notlike "*$target*") {
104+
$env:Path = "$env:Path;$Directory"
105+
}
106+
107+
return $true
108+
}
109+
110+
function Main {
111+
Log 'Checking Python 3.11+'
112+
$python = Find-Python
113+
if (-not $python) {
114+
Die @"
115+
Python $MinMajor.$MinMinor+ was not found.
116+
117+
Install Python from https://www.python.org/downloads/windows/
118+
Make sure to check "Add python.exe to PATH" during installation,
119+
then run this installer again.
120+
"@
121+
}
122+
Write-Host "Using Python: $python"
123+
124+
Log 'Checking built-in venv support'
125+
& $python -m venv --help > $null 2>&1
126+
if ($LASTEXITCODE -ne 0) {
127+
Die 'This Python does not support the built-in venv module. Install a full Python distribution and try again.'
128+
}
129+
130+
Log 'Creating private Python environment'
131+
if (-not (Test-Path $AppHome)) {
132+
New-Item -ItemType Directory -Path $AppHome -Force | Out-Null
133+
}
134+
& $python -m venv $VenvDir
135+
if ($LASTEXITCODE -ne 0) { Die 'Failed to create virtual environment.' }
136+
137+
$venvPython = Join-Path $ScriptsDir 'python.exe'
138+
139+
Log 'Installing / upgrading Slicer URI Bridge'
140+
& $venvPython -m pip install --upgrade pip 2>&1 | Out-Null
141+
& $venvPython -m pip install --upgrade $ProjectSpec
142+
if ($LASTEXITCODE -ne 0) { Die 'pip install failed.' }
143+
144+
Log 'Adding Scripts directory to user PATH'
145+
$added = Add-ToUserPath $ScriptsDir
146+
if ($added) {
147+
Write-Host "Added to PATH: $ScriptsDir"
148+
}
149+
else {
150+
Write-Host 'Already on PATH.'
151+
}
152+
153+
Log 'Creating config if needed'
154+
& $BridgeExe init-config 2>&1 | Out-Null
155+
156+
Log 'Registering URI handlers'
157+
& $BridgeExe register --auto
158+
159+
$configDir = Join-Path $env:APPDATA 'slicer-uri-bridge'
160+
161+
Write-Host @"
162+
163+
Done! Slicer URI Bridge is installed.
164+
165+
Command: slicer-uri-bridge
166+
Config: $configDir\config.toml
167+
Logs: $configDir\bridge.log
168+
Test: slicer-uri-bridge test
169+
Environment: $VenvDir
170+
171+
If "slicer-uri-bridge" is not found, open a new terminal window.
172+
To update later, just run this installer again.
173+
174+
"@
175+
}
176+
177+
Main

src/slicer_uri_bridge/__main__.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
"""Allow running the CLI as ``python -m slicer_uri_bridge``."""
2+
3+
from __future__ import annotations
4+
5+
from .cli import main
6+
7+
raise SystemExit(main())

0 commit comments

Comments
 (0)