Add hidden startup launchers for backend and overlay
This commit is contained in:
47
pc/install_startup_shortcut.ps1
Normal file
47
pc/install_startup_shortcut.ps1
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
[CmdletBinding(SupportsShouldProcess = $true)]
|
||||||
|
param(
|
||||||
|
[switch]$Remove,
|
||||||
|
[switch]$AllUsers
|
||||||
|
)
|
||||||
|
|
||||||
|
$ErrorActionPreference = "Stop"
|
||||||
|
|
||||||
|
$scriptDir = Split-Path -Parent $PSCommandPath
|
||||||
|
$vbsLauncher = Join-Path $scriptDir "start_streamdeck_hidden.vbs"
|
||||||
|
$shortcutName = "Custom Streamdeck Launcher.lnk"
|
||||||
|
|
||||||
|
if (-not (Test-Path $vbsLauncher)) {
|
||||||
|
throw "Launcher file not found: $vbsLauncher"
|
||||||
|
}
|
||||||
|
|
||||||
|
$startupFolder = if ($AllUsers) {
|
||||||
|
[Environment]::GetFolderPath("CommonStartup")
|
||||||
|
} else {
|
||||||
|
[Environment]::GetFolderPath("Startup")
|
||||||
|
}
|
||||||
|
|
||||||
|
$shortcutPath = Join-Path $startupFolder $shortcutName
|
||||||
|
|
||||||
|
if ($Remove) {
|
||||||
|
if (Test-Path $shortcutPath) {
|
||||||
|
if ($PSCmdlet.ShouldProcess($shortcutPath, "Remove startup shortcut")) {
|
||||||
|
Remove-Item -LiteralPath $shortcutPath -Force
|
||||||
|
Write-Host "Removed startup shortcut: $shortcutPath"
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Write-Host "No startup shortcut found at: $shortcutPath"
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($PSCmdlet.ShouldProcess($shortcutPath, "Create startup shortcut")) {
|
||||||
|
$shell = New-Object -ComObject WScript.Shell
|
||||||
|
$shortcut = $shell.CreateShortcut($shortcutPath)
|
||||||
|
$shortcut.TargetPath = "$env:SystemRoot\System32\wscript.exe"
|
||||||
|
$shortcut.Arguments = '"' + $vbsLauncher + '"'
|
||||||
|
$shortcut.WorkingDirectory = $scriptDir
|
||||||
|
$shortcut.Description = "Launch Custom Streamdeck backend and overlay hidden at sign-in."
|
||||||
|
$shortcut.Save()
|
||||||
|
|
||||||
|
Write-Host "Created startup shortcut: $shortcutPath"
|
||||||
|
}
|
||||||
128
pc/start_streamdeck.ps1
Normal file
128
pc/start_streamdeck.ps1
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
param(
|
||||||
|
[switch]$DryRun
|
||||||
|
)
|
||||||
|
|
||||||
|
$ErrorActionPreference = "Stop"
|
||||||
|
|
||||||
|
$repoRoot = Split-Path -Parent $PSScriptRoot
|
||||||
|
$overlayDir = Join-Path $repoRoot "overlay"
|
||||||
|
$dataDir = Join-Path $repoRoot "data"
|
||||||
|
$launcherLog = Join-Path $dataDir "startup-launcher.log"
|
||||||
|
|
||||||
|
if (-not (Test-Path $dataDir)) {
|
||||||
|
New-Item -ItemType Directory -Path $dataDir | Out-Null
|
||||||
|
}
|
||||||
|
|
||||||
|
function Write-LauncherLog {
|
||||||
|
param([string]$Message)
|
||||||
|
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
|
||||||
|
Add-Content -Path $launcherLog -Value "[$timestamp] $Message"
|
||||||
|
}
|
||||||
|
|
||||||
|
function Resolve-PythonPath {
|
||||||
|
$venvPython = Join-Path $repoRoot ".venv\Scripts\python.exe"
|
||||||
|
if (Test-Path $venvPython) {
|
||||||
|
return $venvPython
|
||||||
|
}
|
||||||
|
|
||||||
|
$pythonCmd = Get-Command python -ErrorAction SilentlyContinue
|
||||||
|
if ($null -ne $pythonCmd) {
|
||||||
|
return $pythonCmd.Source
|
||||||
|
}
|
||||||
|
|
||||||
|
throw "Could not find Python. Install Python or create .venv first."
|
||||||
|
}
|
||||||
|
|
||||||
|
function Resolve-NpmPath {
|
||||||
|
$npmCmd = Get-Command npm.cmd -ErrorAction SilentlyContinue
|
||||||
|
if ($null -ne $npmCmd) {
|
||||||
|
return $npmCmd.Source
|
||||||
|
}
|
||||||
|
|
||||||
|
throw "Could not find npm.cmd. Install Node.js/npm first."
|
||||||
|
}
|
||||||
|
|
||||||
|
function Start-HiddenProcess {
|
||||||
|
param(
|
||||||
|
[string]$Name,
|
||||||
|
[string]$FilePath,
|
||||||
|
[string[]]$Arguments,
|
||||||
|
[string]$WorkingDirectory,
|
||||||
|
[string]$StdOutPath,
|
||||||
|
[string]$StdErrPath
|
||||||
|
)
|
||||||
|
|
||||||
|
if ($DryRun) {
|
||||||
|
Write-LauncherLog "DRY RUN -> $Name | $FilePath $($Arguments -join ' ')"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
Start-Process `
|
||||||
|
-FilePath $FilePath `
|
||||||
|
-ArgumentList $Arguments `
|
||||||
|
-WorkingDirectory $WorkingDirectory `
|
||||||
|
-WindowStyle Hidden `
|
||||||
|
-RedirectStandardOutput $StdOutPath `
|
||||||
|
-RedirectStandardError $StdErrPath | Out-Null
|
||||||
|
|
||||||
|
Write-LauncherLog "Started $Name."
|
||||||
|
}
|
||||||
|
|
||||||
|
function Is-BackendRunning {
|
||||||
|
$matches = Get-CimInstance Win32_Process -ErrorAction SilentlyContinue |
|
||||||
|
Where-Object {
|
||||||
|
$_.Name -like "python*" -and
|
||||||
|
$_.CommandLine -and
|
||||||
|
$_.CommandLine -like "*backend.main:app*"
|
||||||
|
}
|
||||||
|
return ($matches | Measure-Object).Count -gt 0
|
||||||
|
}
|
||||||
|
|
||||||
|
function Is-OverlayRunning {
|
||||||
|
$matches = Get-CimInstance Win32_Process -ErrorAction SilentlyContinue |
|
||||||
|
Where-Object {
|
||||||
|
$_.CommandLine -and
|
||||||
|
$_.CommandLine -like "*custom-streamdeck*overlay*"
|
||||||
|
}
|
||||||
|
return ($matches | Measure-Object).Count -gt 0
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$pythonPath = Resolve-PythonPath
|
||||||
|
$npmPath = Resolve-NpmPath
|
||||||
|
|
||||||
|
if (-not (Test-Path (Join-Path $repoRoot "frontend\dist\index.html"))) {
|
||||||
|
Write-LauncherLog "Warning: frontend/dist is missing. Build frontend for production view."
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Is-BackendRunning) {
|
||||||
|
Write-LauncherLog "Backend already running. Skipping backend launch."
|
||||||
|
} else {
|
||||||
|
$backendOut = Join-Path $dataDir "backend.stdout.log"
|
||||||
|
$backendErr = Join-Path $dataDir "backend.stderr.log"
|
||||||
|
Start-HiddenProcess `
|
||||||
|
-Name "backend" `
|
||||||
|
-FilePath $pythonPath `
|
||||||
|
-Arguments @("-m", "uvicorn", "backend.main:app", "--host", "127.0.0.1", "--port", "8000") `
|
||||||
|
-WorkingDirectory $repoRoot `
|
||||||
|
-StdOutPath $backendOut `
|
||||||
|
-StdErrPath $backendErr
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Is-OverlayRunning) {
|
||||||
|
Write-LauncherLog "Overlay already running. Skipping overlay launch."
|
||||||
|
} else {
|
||||||
|
$overlayOut = Join-Path $dataDir "overlay.stdout.log"
|
||||||
|
$overlayErr = Join-Path $dataDir "overlay.stderr.log"
|
||||||
|
Start-HiddenProcess `
|
||||||
|
-Name "overlay" `
|
||||||
|
-FilePath $npmPath `
|
||||||
|
-Arguments @("run", "start") `
|
||||||
|
-WorkingDirectory $overlayDir `
|
||||||
|
-StdOutPath $overlayOut `
|
||||||
|
-StdErrPath $overlayErr
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
Write-LauncherLog "Launcher failed: $($_.Exception.Message)"
|
||||||
|
throw
|
||||||
|
}
|
||||||
11
pc/start_streamdeck_hidden.vbs
Normal file
11
pc/start_streamdeck_hidden.vbs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
Option Explicit
|
||||||
|
|
||||||
|
Dim shell, fso, scriptDir, psScript, command
|
||||||
|
Set shell = CreateObject("WScript.Shell")
|
||||||
|
Set fso = CreateObject("Scripting.FileSystemObject")
|
||||||
|
|
||||||
|
scriptDir = fso.GetParentFolderName(WScript.ScriptFullName)
|
||||||
|
psScript = """" & fso.BuildPath(scriptDir, "start_streamdeck.ps1") & """"
|
||||||
|
|
||||||
|
command = "powershell.exe -NoProfile -ExecutionPolicy Bypass -WindowStyle Hidden -File " & psScript
|
||||||
|
shell.Run command, 0, False
|
||||||
Reference in New Issue
Block a user