33
44 Invoked (via launch.vbs, hidden) with one or more file paths as arguments. Uploads each selected
55 file to the "ComputerShared" space (a top-level folder in your Drive) over WebDAV, shows a small
6- tray notification, and appends a line to send.log so problems can be diagnosed. Configuration
6+ tray notification, and writes a detailed send.log so any problem can be diagnosed. Configuration
77 (WebDAV URL + DPAPI-encrypted token + options) lives in %LOCALAPPDATA%\OpenCoperLock\config.json.
88#>
9- $ErrorActionPreference = ' Stop'
109$dir = Join-Path $env: LOCALAPPDATA ' OpenCoperLock'
1110$cfgPath = Join-Path $dir ' config.json'
1211$icon = Join-Path $dir ' opencoperlock.ico'
1312$logPath = Join-Path $dir ' send.log'
1413
14+ # Bulletproof logging via .NET so we always get a trace, even if something fails very early.
1515function Log ($msg ) {
16- try { Add-Content - LiteralPath $logPath - Value (" {0} {1}" -f (Get-Date - Format ' yyyy-MM-dd HH:mm:ss' ), $msg ) } catch { }
16+ try {
17+ if (-not (Test-Path $dir )) { New-Item - ItemType Directory - Force - Path $dir | Out-Null }
18+ [System.IO.File ]::AppendAllText($logPath , (" {0} {1}`r`n " -f (Get-Date - Format ' yyyy-MM-dd HH:mm:ss' ), $msg ))
19+ } catch { }
1720}
21+ # Any uncaught error is logged instead of vanishing with the hidden window.
22+ trap { Log " FATAL: $ ( $_.Exception.Message ) " ; exit 1 }
23+
24+ Log " === send.ps1 start; args=$ ( $args.Count ) : $ ( $args -join ' | ' ) "
1825
1926function Show-Toast ($title , $text ) {
2027 if ($script :notify -eq $false ) { return }
@@ -30,36 +37,44 @@ function Show-Toast($title, $text) {
3037 } catch { Log " toast failed: $ ( $_.Exception.Message ) " }
3138}
3239
33- Log " invoked with $ ( $args .Count ) arg(s): $ ( $args -join ' | ' ) "
40+ if ( -not ( Test-Path $cfgPath )) { Log ' no config.json - run the installer ' ; Show-Toast ' OpenCoperLock ' ' Not configured yet - run the installer. ' ; exit 1 }
3441
35- if (-not (Test-Path $cfgPath )) { Log ' no config' ; Show-Toast ' OpenCoperLock' ' Not configured yet - run the installer.' ; exit 1 }
36-
37- $cfg = Get-Content $cfgPath - Raw | ConvertFrom-Json
42+ $cfg = Get-Content $cfgPath - Raw | ConvertFrom-Json
3843$base = ($cfg.base ).TrimEnd(' /' )
3944$script :notify = -not ($cfg.PSObject.Properties.Name -contains ' notify' -and $cfg.notify -eq $false )
45+ Log " config loaded; base=$base notify=$script :notify "
4046
4147# Decrypt the DPAPI-protected token.
42- $sec = ConvertTo-SecureString $cfg.token
43- $bstr = [Runtime.InteropServices.Marshal ]::SecureStringToBSTR($sec )
44- $tok = [Runtime.InteropServices.Marshal ]::PtrToStringAuto($bstr )
45- [Runtime.InteropServices.Marshal ]::ZeroFreeBSTR($bstr )
48+ try {
49+ $sec = ConvertTo-SecureString $cfg.token # DPAPI, current user
50+ $bstr = [Runtime.InteropServices.Marshal ]::SecureStringToBSTR($sec )
51+ $tok = [Runtime.InteropServices.Marshal ]::PtrToStringAuto($bstr )
52+ [Runtime.InteropServices.Marshal ]::ZeroFreeBSTR($bstr )
53+ } catch { Log " token decrypt failed: $ ( $_.Exception.Message ) " ; Show-Toast ' OpenCoperLock' ' Token unreadable - re-run the installer.' ; exit 1 }
54+ Log " token decrypted; length=$ ( $tok.Length ) "
55+
56+ $curl = " $env: SystemRoot \System32\curl.exe"
57+ if (-not (Test-Path $curl )) { $curl = ' curl.exe' } # fall back to PATH
4658
4759$files = @ ($args | Where-Object { $_ -and (Test-Path - LiteralPath $_ - PathType Leaf) })
48- if ($files.Count -eq 0 ) { Log ' no files after filter' ; Show-Toast ' OpenCoperLock' ' No files to send (folders are skipped).' ; exit 0 }
60+ Log " files to send: $ ( $files.Count ) "
61+ if ($files.Count -eq 0 ) { Show-Toast ' OpenCoperLock' ' No files to send (folders are skipped).' ; exit 0 }
4962
5063$cred = " me:$tok "
5164# Make sure the space exists (a 405 "already there" is fine and ignored).
52- & curl.exe - s - u $cred - X MKCOL " $base /ComputerShared/" | Out-Null
65+ $mk = & $curl - s - o NUL - w " %{http_code}" - u $cred - X MKCOL " $base /ComputerShared/" 2>&1
66+ Log " MKCOL ComputerShared -> $mk (curl exit $LASTEXITCODE )"
5367
5468$ok = 0 ; $fail = 0
5569foreach ($f in $files ) {
56- $name = [uri ]::EscapeDataString((Split-Path - LiteralPath $f - Leaf))
57- $code = & curl.exe - s - o NUL - w " %{http_code}" - u $cred - T $f " $base /ComputerShared/$name "
58- Log " PUT $f -> $base /ComputerShared/$name = $code "
59- if ($code -match ' ^2' ) { $ok ++ } else { $fail ++ }
70+ $leaf = Split-Path - LiteralPath $f - Leaf
71+ $name = [uri ]::EscapeDataString($leaf )
72+ $code = & $curl - s - o NUL - w " %{http_code}" - u $cred - T $f " $base /ComputerShared/$name " 2>&1
73+ Log " PUT '$leaf ' -> $base /ComputerShared/$name = $code (curl exit $LASTEXITCODE )"
74+ if (" $code " -match ' ^2\d\d' ) { $ok ++ } else { $fail ++ }
6075}
6176$tok = $null ; $cred = $null
6277
63- Log " done: ok=$ok fail=$fail "
78+ Log " === done: ok=$ok fail=$fail "
6479if ($fail -eq 0 ) { Show-Toast ' OpenCoperLock' " Sent $ok file(s) to ComputerShared." }
6580else { Show-Toast ' OpenCoperLock' " Sent $ok , $fail failed - see send.log." }
0 commit comments