DesktopAppInstaller on this host returns 0x8a15000f with an empty winget index; source reset does not recover it. Fetch MinGit and the go.dev windows-amd64 zip into LOCALAPPDATA instead.
159 lines
6.4 KiB
PowerShell
159 lines
6.4 KiB
PowerShell
# rclone-dropbox-bisync Windows setup
|
|
# Paths: D: (volume label DataStorage) \Dropbox and \rclone-bisync
|
|
# Paste into PowerShell, or: irm <raw-url>/windows/bootstrap.ps1 | iex
|
|
|
|
$ErrorActionPreference = 'Stop'
|
|
$GitBase = 'https://git.denkena-consulting.com/f-denkena'
|
|
$PackRepo = "$GitBase/rclone-dropbox-bisync.git"
|
|
$RcloneRepo = "$GitBase/rclone.git"
|
|
$Src = Join-Path $env:LOCALAPPDATA 'rclone-dropbox-bisync\src'
|
|
$Dest = Join-Path $env:LOCALAPPDATA 'rclone-dropbox-bisync'
|
|
$Dropbox = 'D:\Dropbox'
|
|
$Workdir = 'D:\rclone-bisync'
|
|
|
|
# Do not use winget: 0x8a15000f (empty source cache) is common and not recoverable
|
|
# from this script. Fetch portable MinGit + Go into LOCALAPPDATA instead.
|
|
$Tools = Join-Path $Dest 'tools'
|
|
|
|
function Prepend-UserPath($Dir) {
|
|
$userPath = [Environment]::GetEnvironmentVariable('Path', 'User')
|
|
if ([string]::IsNullOrEmpty($userPath)) { $userPath = '' }
|
|
if ($userPath -notlike "*$Dir*") {
|
|
[Environment]::SetEnvironmentVariable('Path', $(if ($userPath) { "$Dir;$userPath" } else { $Dir }), 'User')
|
|
}
|
|
if ($env:Path -notlike "*$Dir*") { $env:Path = "$Dir;$env:Path" }
|
|
}
|
|
|
|
function Get-File($Url, $Out) {
|
|
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
|
|
Invoke-WebRequest -Uri $Url -OutFile $Out -UseBasicParsing
|
|
}
|
|
|
|
function Ensure-Git {
|
|
if (Get-Command git -ErrorAction SilentlyContinue) { return }
|
|
$root = Join-Path $Tools 'mingit'
|
|
$cmd = Join-Path $root 'cmd'
|
|
if (-not (Test-Path (Join-Path $cmd 'git.exe'))) {
|
|
Write-Host 'Fetching MinGit...'
|
|
$rel = Invoke-RestMethod -Uri 'https://api.github.com/repos/git-for-windows/git/releases/latest'
|
|
$asset = $rel.assets |
|
|
Where-Object { $_.name -match '^MinGit-.+-64-bit\.zip$' -and $_.name -notmatch 'busybox' } |
|
|
Select-Object -First 1
|
|
if (-not $asset) { throw 'No MinGit-*-64-bit.zip on git-for-windows latest release' }
|
|
$zip = Join-Path $env:TEMP $asset.name
|
|
Get-File $asset.browser_download_url $zip
|
|
New-Item -ItemType Directory -Force -Path $root | Out-Null
|
|
Expand-Archive -Path $zip -DestinationPath $root -Force
|
|
}
|
|
Prepend-UserPath $cmd
|
|
if (-not (Get-Command git -ErrorAction SilentlyContinue)) {
|
|
throw "git.exe missing under $cmd"
|
|
}
|
|
}
|
|
|
|
function Ensure-Go {
|
|
if (Get-Command go -ErrorAction SilentlyContinue) { return }
|
|
$root = Join-Path $Tools 'go'
|
|
$bin = Join-Path $root 'go\bin'
|
|
if (-not (Test-Path (Join-Path $bin 'go.exe'))) {
|
|
Write-Host 'Fetching Go...'
|
|
$dl = Invoke-RestMethod -Uri 'https://go.dev/dl/?mode=json'
|
|
$file = $null
|
|
foreach ($rel in $dl) {
|
|
$file = $rel.files |
|
|
Where-Object { $_.os -eq 'windows' -and $_.arch -eq 'amd64' -and $_.kind -eq 'archive' } |
|
|
Select-Object -First 1
|
|
if ($file) { break }
|
|
}
|
|
if (-not $file) { throw 'No windows-amd64 Go archive on go.dev/dl' }
|
|
$zip = Join-Path $env:TEMP $file.filename
|
|
Get-File "https://go.dev/dl/$($file.filename)" $zip
|
|
New-Item -ItemType Directory -Force -Path $root | Out-Null
|
|
Expand-Archive -Path $zip -DestinationPath $root -Force
|
|
}
|
|
Prepend-UserPath $bin
|
|
if (-not (Get-Command go -ErrorAction SilentlyContinue)) {
|
|
throw "go.exe missing under $bin"
|
|
}
|
|
}
|
|
|
|
Ensure-Git
|
|
Ensure-Go
|
|
|
|
New-Item -ItemType Directory -Force -Path $Src, (Join-Path $Dest 'bin') | Out-Null
|
|
if (-not (Test-Path (Join-Path $Src 'packaging\.git'))) {
|
|
git clone --depth 1 $PackRepo (Join-Path $Src 'packaging')
|
|
} else {
|
|
git -C (Join-Path $Src 'packaging') pull --ff-only
|
|
}
|
|
if (-not (Test-Path (Join-Path $Src 'rclone\.git'))) {
|
|
git clone --depth 1 --branch bisync-delta-list $RcloneRepo (Join-Path $Src 'rclone')
|
|
} else {
|
|
git -C (Join-Path $Src 'rclone') fetch origin bisync-delta-list
|
|
git -C (Join-Path $Src 'rclone') checkout bisync-delta-list
|
|
git -C (Join-Path $Src 'rclone') pull --ff-only
|
|
}
|
|
|
|
Write-Host 'Building rclone (forked)...'
|
|
Push-Location (Join-Path $Src 'rclone')
|
|
$env:CGO_ENABLED = '0'
|
|
go build -trimpath -o (Join-Path $Dest 'bin\rclone.exe') .
|
|
Pop-Location
|
|
Write-Host 'Building rclone-bisyncd...'
|
|
Push-Location (Join-Path $Src 'packaging\cmd\rclone-bisyncd')
|
|
go build -trimpath -o (Join-Path $Dest 'bin\rclone-bisyncd.exe') .
|
|
Pop-Location
|
|
|
|
Copy-Item -Force (Join-Path $Src 'packaging\windows\tray.ps1') (Join-Path $Dest 'tray.ps1')
|
|
|
|
if (-not (Test-Path 'D:\')) { throw 'D: is missing (expected DataStorage volume)' }
|
|
if (-not (Test-Path $Dropbox)) { throw "Dropbox folder not found: $Dropbox" }
|
|
New-Item -ItemType Directory -Force -Path $Workdir | Out-Null
|
|
$testFile = Join-Path $Dropbox 'RCLONE_TEST'
|
|
if (-not (Test-Path $testFile)) { New-Item -ItemType File -Path $testFile | Out-Null }
|
|
|
|
$cfgPath = Join-Path $Dest 'config.json'
|
|
@{
|
|
enabled = $false
|
|
path1 = $Dropbox
|
|
path2 = 'dropbox:'
|
|
workdir = $Workdir
|
|
interval_minutes = 15
|
|
rclone = (Join-Path $Dest 'bin\rclone.exe')
|
|
check_filename = 'RCLONE_TEST'
|
|
session_name = 'datastorage-dropbox'
|
|
} | ConvertTo-Json | Set-Content -Encoding UTF8 $cfgPath
|
|
$env:RCLONE_BISYNC_CONFIG = $cfgPath
|
|
|
|
$bin = Join-Path $Dest 'bin'
|
|
$userPath = [Environment]::GetEnvironmentVariable('Path', 'User')
|
|
if ($userPath -notlike "*$bin*") {
|
|
[Environment]::SetEnvironmentVariable('Path', "$bin;$userPath", 'User')
|
|
}
|
|
|
|
$run = 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Run'
|
|
$tray = Join-Path $Dest 'tray.ps1'
|
|
New-ItemProperty -Path $run -Name 'rclone-dropbox-bisync-tray' -PropertyType String -Force `
|
|
-Value "powershell.exe -NoProfile -WindowStyle Hidden -ExecutionPolicy Bypass -File `"$tray`"" | Out-Null
|
|
|
|
$daemon = Join-Path $Dest 'bin\rclone-bisyncd.exe'
|
|
schtasks /Delete /F /TN 'rclone-dropbox-bisync' 2>$null
|
|
schtasks /Create /F /TN 'rclone-dropbox-bisync' /SC ONLOGON /RL LIMITED /TR "`"$daemon`"" | Out-Null
|
|
New-ItemProperty -Path $run -Name 'rclone-dropbox-bisync-daemon' -PropertyType String -Force `
|
|
-Value "`"$daemon`"" | Out-Null
|
|
|
|
Start-Process powershell.exe -WindowStyle Hidden -ArgumentList @(
|
|
'-NoProfile', '-ExecutionPolicy', 'Bypass', '-File', $tray
|
|
)
|
|
Start-Process $daemon -WindowStyle Hidden
|
|
|
|
Write-Host @"
|
|
Configured:
|
|
path1 $Dropbox (D: DataStorage)
|
|
workdir $Workdir
|
|
session datastorage-dropbox (shared with Linux)
|
|
daemon looping; 15 min after each run; mkdir lock
|
|
If dropbox: has RCLONE_TEST and listings are missing, the daemon
|
|
dry-run --resync then live --resync on its own. Never after a failed run.
|
|
"@
|