# install-host.ps1 # Registers rclonex native-messaging host so Brave can launch it. # # Usage: .\install-host.ps1 # Optional: .\install-host.ps1 -ExtensionId # # Writes manifest to host\com.rcjav.host.json with the correct path + extension ID allowed, # then registers it in HKLM (requires admin - script self-elevates if needed) AND HKCU. # HKLM is required on some Brave installs; HKCU alone is not always honored. param( [string]$ExtensionId = "" ) $ErrorActionPreference = "Stop" $hostDir = $PSScriptRoot $batPath = Join-Path $hostDir "rcjav-host.bat" if (-not (Test-Path $batPath)) { throw "Host bat not found: $batPath" } $manifestPath = Join-Path $hostDir "com.rcjav.host.json" $allowlistPath = Join-Path $hostDir "allowed-extension-ids.json" # Self-elevate before writing the manifest or HKLM registry entries. Some # installs keep the host folder under admin-owned permissions. $isAdmin = ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole( [Security.Principal.WindowsBuiltInRole]::Administrator) if (-not $isAdmin) { Write-Host "Not running as admin - relaunching elevated..." $args = @( "-NoProfile", "-ExecutionPolicy", "Bypass", "-File", $PSCommandPath ) if ($ExtensionId) { $args += @("-ExtensionId", $ExtensionId) } Start-Process pwsh -Verb RunAs -ArgumentList $args exit } $extensionIds = @() if (Test-Path $allowlistPath) { try { $allowlist = Get-Content $allowlistPath -Raw | ConvertFrom-Json if ($allowlist.allowed_extension_ids) { $props = $allowlist.allowed_extension_ids.PSObject.Properties foreach ($prop in $props) { $id = [string]$prop.Value if ($id -match '^[a-p]{32}$' -and $extensionIds -notcontains $id) { $extensionIds += $id } } } } catch { throw "Failed to read $allowlistPath`: $($_.Exception.Message)" } } if ($ExtensionId) { if ($ExtensionId -notmatch '^[a-p]{32}$') { throw "Invalid extension ID: $ExtensionId" } if ($extensionIds -notcontains $ExtensionId) { $extensionIds += $ExtensionId } } if ($extensionIds.Count -eq 0) { throw "No extension IDs configured. Add IDs to $allowlistPath or pass -ExtensionId." } $allowedOrigins = @($extensionIds | ForEach-Object { "chrome-extension://$_/" }) $manifest = [ordered]@{ name = "com.rcjav.host" description = "rclonex native messaging host (rc-jav bridge)" path = $batPath type = "stdio" allowed_origins = @($allowedOrigins) } $content = $manifest | ConvertTo-Json -Depth 4 # UTF-8 WITHOUT BOM - Chrome/Brave rejects manifests with a BOM. [System.IO.File]::WriteAllText($manifestPath, $content, [System.Text.UTF8Encoding]::new($false)) Write-Host "Manifest written: $manifestPath" # Register in HKLM - required on some Brave installs. $keys = @( 'HKLM:\Software\BraveSoftware\Brave-Browser\NativeMessagingHosts\com.rcjav.host', 'HKLM:\Software\Google\Chrome\NativeMessagingHosts\com.rcjav.host', 'HKLM:\Software\WOW6432Node\Google\Chrome\NativeMessagingHosts\com.rcjav.host', 'HKLM:\Software\Chromium\NativeMessagingHosts\com.rcjav.host', # HKCU as belt-and-suspenders for installs that prefer it 'HKCU:\Software\BraveSoftware\Brave-Browser\NativeMessagingHosts\com.rcjav.host', 'HKCU:\Software\Google\Chrome\NativeMessagingHosts\com.rcjav.host', 'HKCU:\Software\Chromium\NativeMessagingHosts\com.rcjav.host' ) foreach ($k in $keys) { try { New-Item -Path $k -Force -ErrorAction Stop | Out-Null Set-Item -Path $k -Value $manifestPath Write-Host " Set: $k" } catch { Write-Host " FAILED: $k ($($_.Exception.Message))" } } Write-Host "" Write-Host "Manifest contents:" Write-Host "-------------------" Write-Host $content Write-Host "-------------------" Write-Host "" Write-Host "Fully restart Brave (kill all brave.exe processes, then reopen) for the registry" Write-Host "entries to be picked up. Then click rclonex toolbar > Ping host." Read-Host "Press Enter to close"