# rclone-dropbox-bisync Windows setup # Paths: D: (volume label DataStorage) \Dropbox and \rclone-bisync # Paste into PowerShell, or: irm /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' function Ensure-Cmd($Name, $WingetId) { if (Get-Command $Name -ErrorAction SilentlyContinue) { return } if (-not (Get-Command winget -ErrorAction SilentlyContinue)) { throw "Need $Name on PATH (or winget to install $WingetId)" } winget install -e --id $WingetId --accept-package-agreements --accept-source-agreements $env:Path = [Environment]::GetEnvironmentVariable('Path', 'Machine') + ';' + [Environment]::GetEnvironmentVariable('Path', 'User') } Ensure-Cmd git Git.Git Ensure-Cmd go GoLang.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. "@