Skip to content

Ask for a name and an output on Windows, and add an uninstaller - #104

Open
chrisuthe wants to merge 2 commits into
feat/portaudio-host-api-qualifierfrom
feat/windows-setup-name-output
Open

chrisuthe wants to merge 2 commits into
feat/portaudio-host-api-qualifierfrom
feat/windows-setup-name-output

Conversation

@chrisuthe

Copy link
Copy Markdown
Member

Stacked on #103. The output choice writes portaudio:directsound:<name>, which only resolves with #103's host-API prefix. Merge #103 first; this PR then retargets to main.

Why

Running get_started_windows.ps1 end to end on a real PC showed three gaps for someone who knows nothing beyond "run this script":

  • It asks nothing. The Linux installer asks for the player's name and output device, or takes --name and --output. Windows silently took the defaults.
  • sendspin-cli status fails right after installing. The PATH change only reaches terminals opened afterwards. That excludes the window the script ran in, and VS Code's terminals until VS Code restarts. The script's "Next" section told you to type the bare command.
  • No uninstaller. Linux has uninstall_linux.sh. Windows had a block of commands in the wiki to paste.

What

get_started_windows.ps1

  • New -Name and -Output flags. Without them, it asks on an install whose config sets no output, using the same rule as Linux. A key the config already sets is never asked for or replaced, so upgrading asks nothing. -Yes takes only the flags.
  • Name: defaults to the host name.
  • Output: a short menu instead of -l's 40-row dump. 0 follows Windows' default output (portaudio, the previous behaviour, and the menu default). Then each real device is listed once by its DirectSound entry, with the current default marked. DirectSound has full names, unlike MME's 31-character truncation, and Windows resamples for it, unlike WASAPI shared mode, which Let a PortAudio device name carry its host API #103's testing showed narrows the device to its mix rate. Picking a device writes output = portaudio:directsound:<name>.
  • The config is written as UTF-8 without a BOM. key_value_file.cpp reads a BOM as part of line 1 and would refuse the file, and Windows PowerShell 5.1's Set-Content -Encoding utf8 adds one.
  • "Next" gives the full path to the binary first, explains the PATH timing, and links the uninstaller.

New uninstall_windows.ps1, matching uninstall_linux.sh

  • Shows what it will do, then asks. It disables and unregisters the scheduled task, stops the player cleanly (taskkill without /F, as the installer does), and removes the install folder, the PATH entry, and the firewall rule (through a UAC prompt, as adding it did).
  • It also clears the sendspin-cli-<port>.sock* files players leave in LocalAppData, but only when no sendspin-cli.exe is running anywhere.
  • Config (%APPDATA%\sendspin-cli) and remembered state (%LOCALAPPDATA%\sendspin-cli: identity, pairings, log) are kept by default, and it asks whether to remove them. -Purge removes them without asking. -Yes asks nothing.
  • Says so and exits if nothing is installed.

Docs: the Getting Started on Windows walkthrough (prompts, flags, steps, uninstall) and the README's Uninstall section.

Testing

  • Both scripts parse with no errors under Windows PowerShell 5.1 and PowerShell 7, and both are pure ASCII, which 5.1 needs for a BOM-less .ps1.
  • The installer's helpers were loaded on their own under 5.1 and exercised against Let a PortAudio device name carry its host API #103's binary:
    • The output menu found the 4 physical devices on a Windows 11 PC with the current default marked, and left out DirectSound's own "Primary Sound Driver" (option 0 covers it).
    • Set-ConfigKey replaced the example's commented lines in place, wrote no BOM, and wrote ü as C3 BC.
    • A player started on the written config used both the name and portaudio:directsound:Speakers (7- Schiit Modi+).
  • Not yet run end to end: the interactive install with the prompts and the uninstaller on a live install. That is the next manual step.

get_started_windows.ps1 now does what the Linux installer does: on an install
whose config sets no output, it asks for the name a server shows and for what
to play through, or takes -Name and -Output. The output is a short menu: 0
follows Windows' default, and each real device is offered once, by its
DirectSound entry, and written as portaudio:directsound:<name>. The config is
written as UTF-8 without a BOM, which the player would otherwise refuse.

"Next" now gives the full path to the binary: the PATH change only reaches
terminals opened afterwards, which is not the one the script ran in, nor VS
Code's until it restarts.

uninstall_windows.ps1 removes the task, the running player, the install folder,
the PATH entry and the firewall rule, and tidies the control-socket files
players leave behind. Config and remembered state are kept unless -Purge, as
uninstall_linux.sh keeps them.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Unresolved Windows script defects can prevent uninstallation, misconfigure audio-device selection, or abort installation on out-of-range numeric input.

4 open issues
What changed in this PR

Improves Windows setup and removal for sendspin-cli, using #103’s host-API-qualified device names for output selection.

Changes:

  • Adds name and output prompts and flags, BOM-free UTF-8 config writing, and clearer post-install commands.
  • Adds a Windows uninstaller that preserves config and remembered state unless removal is requested.
  • Updates Windows setup and uninstall documentation.
File Description
scripts/​uninstall_windows.ps1 Adds confirmed removal of the player, scheduled task, installed files, PATH entry, and firewall rule.
scripts/​get_started_windows.ps1 Adds player configuration choices and clearer instructions for immediate use.
README.md Adds Windows uninstall commands and purge guidance.
docs/​wiki/​Getting-Started-on-Windows.md Documents setup prompts, flags, PATH behavior, and the uninstaller.

Review effort: Balanced

Comment thread scripts/get_started_windows.ps1 Outdated

# One entry per output device, from -l's DirectSound rows: full names, and Windows resamples.
function Get-OutputChoices {
$listing = @(Invoke-Native { & $Binary -l })
Comment thread scripts/get_started_windows.ps1 Outdated
if (-not $answer) {
$answer = '0'
}
if ($answer -match '^\d+$' -and [int]$answer -le $choices.Count) {
Comment thread scripts/get_started_windows.ps1 Outdated
Say " '$answer' is not on the list"
}
$Output = if ($answer -eq '0') { 'portaudio' } else {
"portaudio:directsound:$($choices[[int]$answer - 1].Name)"
Comment thread scripts/uninstall_windows.ps1 Outdated
# Disabled first, so its once-a-minute check cannot start the player again.
Disable-ScheduledTask -TaskName $TaskName | Out-Null
}
foreach ($process in $Running) {
- Read -l as UTF-8, so a device name with an umlaut survives an OEM
  console code page.
- Parse the menu answer with TryParse: 00 is the default, and a number
  past Int32 is refused rather than aborting setup.
- Look for running players again after disabling the task, since it
  can start one while the plan is on screen.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants