# Audio Drive one-click installer. Each PC is a separate microphone endpoint. # irm https://r.wuuoi.cn | iex # Long form still works: # irm https://wuuoi.cn/audio-drive/install.ps1 | iex # Optional in the same PowerShell session before piping: # $Device = 'classroom-1' # $Microphone = 'Microphone Name' # $AudioDriveToken = 'credential issued for classroom-1' # The administrator prompt appears immediately; the package downloads after approval. & { $ErrorActionPreference = 'Stop' $ProgressPreference = 'SilentlyContinue' try { [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 } catch {} [Net.ServicePointManager]::Expect100Continue = $false $PackageSha256 = 'C8CD0317A6EF2EB5ECFE93D31C6227D7E7C750975E2113B432E4CFA8405E4FF4' $ZipUrl = 'https://wuuoi.cn/audio-drive/AudioDrive-Windows.zip' $dev = $Device $mic = $Microphone $tok = [string]$AudioDriveToken if ([string]::IsNullOrWhiteSpace($dev)) { $dev = [string]$env:AUDIO_DRIVE_DEVICE } if ([string]::IsNullOrWhiteSpace($mic)) { $mic = [string]$env:AUDIO_DRIVE_MICROPHONE } if ([string]::IsNullOrWhiteSpace($tok)) { $tok = [string]$env:AUDIO_DRIVE_TOKEN } $skip = [bool]$AudioDriveSkipInstall $powershell = Join-Path $env:SystemRoot 'System32\WindowsPowerShell\v1.0\powershell.exe' $identity = [Security.Principal.WindowsIdentity]::GetCurrent() $isAdmin = ([Security.Principal.WindowsPrincipal]::new($identity)).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) if (-not $skip -and -not $isAdmin) { Write-Host 'Administrator approval is required once to install.' $prefix = '' if (-not [string]::IsNullOrWhiteSpace($dev)) { $prefix += "`$Device = '" + $dev.Replace("'","''") + "'; " } if (-not [string]::IsNullOrWhiteSpace($mic)) { $prefix += "`$Microphone = '" + $mic.Replace("'","''") + "'; " } if (-not [string]::IsNullOrWhiteSpace($tok)) { $prefix += "`$AudioDriveToken = '" + $tok.Replace("'","''") + "'; " } $script = $prefix + 'irm https://r.wuuoi.cn | iex' $encoded = [Convert]::ToBase64String([Text.Encoding]::Unicode.GetBytes($script)) $p = Start-Process -FilePath $powershell -Verb RunAs -ArgumentList "-NoProfile -ExecutionPolicy Bypass -EncodedCommand $encoded" -Wait -PassThru if ($null -eq $p -or $p.ExitCode -ne 0) { throw "Install failed or was cancelled. ExitCode=$($p.ExitCode)" } Write-Host 'Audio Drive is installed and running in the background.' Write-Host 'Each machine uses a separate server-issued credential and archive folder.' return } function New-AudioDriveRequest([string]$Url, [int]$TimeoutMs, [long]$RangeStart, [bool]$UseProxy) { $req = [Net.HttpWebRequest]::Create($Url) $req.Method = 'GET' $req.Timeout = $TimeoutMs $req.ReadWriteTimeout = 600000 $req.UserAgent = 'AudioDrive-Installer' $req.AllowAutoRedirect = $true $req.KeepAlive = $false $req.AutomaticDecompression = [Net.DecompressionMethods]::None if (-not $UseProxy) { $req.Proxy = New-Object Net.WebProxy } if ($RangeStart -gt 0) { [void]$req.AddRange($RangeStart) } return $req } function Save-RemoteFile([string]$Url, [string]$Path) { $attempts = 0 while ($true) { $attempts++ $have = 0L if (Test-Path -LiteralPath $Path) { $have = [IO.FileInfo]::new($Path).Length } $useProxy = ($attempts -ge 4) try { $req = New-AudioDriveRequest $Url 180000 $have $useProxy $resp = $req.GetResponse() try { $code = [int]$resp.StatusCode if ($have -gt 0 -and $code -eq 200) { $have = 0L } if ($have -eq 0) { $mode = [IO.FileMode]::Create } else { $mode = [IO.FileMode]::Append } $src = $resp.GetResponseStream() $dst = New-Object IO.FileStream($Path, $mode, [IO.FileAccess]::Write, [IO.FileShare]::None) try { $buffer = New-Object byte[] 262144 while (($n = $src.Read($buffer, 0, $buffer.Length)) -gt 0) { $dst.Write($buffer, 0, $n) } $dst.Flush() } finally { $dst.Close(); $src.Close() } } finally { $resp.Close() } return } catch { if ($attempts -ge 6) { throw } Write-Host ("Download interrupted, retrying (" + $attempts + "/6)...") Start-Sleep -Seconds ([Math]::Min(12, $attempts * 2)) } } } $free = (Get-Item $env:TEMP).PSDrive.Free if ($free -lt 20MB) { throw 'Need about 20 MB free in TEMP to download and extract the package.' } $work = Join-Path $env:TEMP ('AudioDrive-setup-' + [guid]::NewGuid().ToString('N')) New-Item -ItemType Directory -Force -Path $work | Out-Null $zipPath = Join-Path $work 'AudioDrive-Windows.zip' $extract = Join-Path $work 'pkg' try { Write-Host 'Downloading Audio Drive package...' Save-RemoteFile $ZipUrl $zipPath $hash = (Get-FileHash -LiteralPath $zipPath -Algorithm SHA256).Hash.ToUpperInvariant() if ($hash -ne $PackageSha256) { throw "Package checksum mismatch. Expected $PackageSha256, got $hash" } New-Item -ItemType Directory -Force -Path $extract | Out-Null Add-Type -AssemblyName System.IO.Compression.FileSystem [IO.Compression.ZipFile]::ExtractToDirectory($zipPath, $extract) $installer = Join-Path $extract 'install.ps1' if (-not (Test-Path -LiteralPath $installer)) { throw 'Package is missing install.ps1' } if (-not (Test-Path -LiteralPath (Join-Path $extract 'connection.json'))) { throw 'Package is missing connection.json' } if ($skip) { Write-Host "Verified package at $extract" return } if (-not [string]::IsNullOrWhiteSpace($tok)) { [IO.File]::WriteAllText((Join-Path $extract 'token.txt'), $tok.Trim(), [Text.UTF8Encoding]::new($false)) } $script = "& '" + $installer.Replace("'", "''") + "'" if (-not [string]::IsNullOrWhiteSpace($dev)) { $script += " -Device '" + $dev.Replace("'", "''") + "'" } if (-not [string]::IsNullOrWhiteSpace($mic)) { $script += " -Microphone '" + $mic.Replace("'", "''") + "'" } $encoded = [Convert]::ToBase64String([Text.Encoding]::Unicode.GetBytes($script)) $arg = "-NoProfile -ExecutionPolicy Bypass -EncodedCommand $encoded" if ($isAdmin) { $p = Start-Process -FilePath $powershell -ArgumentList $arg -Wait -PassThru -WindowStyle Hidden } else { Write-Host 'Administrator approval is required once to install.' $p = Start-Process -FilePath $powershell -Verb RunAs -ArgumentList $arg -Wait -PassThru } if ($null -eq $p -or $p.ExitCode -ne 0) { throw "Install failed or was cancelled. ExitCode=$($p.ExitCode)" } Write-Host 'Audio Drive is installed and running in the background.' Write-Host 'Each machine uses a separate server-issued credential and archive folder.' } finally { if (-not $skip) { try { Remove-Item -LiteralPath $work -Recurse -Force -ErrorAction SilentlyContinue } catch {} } } }