407 lines
23 KiB
PowerShell
407 lines
23 KiB
PowerShell
#Requires -Version 5.1
|
|
<#
|
|
Installer AdHoc Backup (GUI) - v1.3.5
|
|
- Fix: editing nel tab Config -> niente più "indice null" (usa $sender.Tag per mappare il key)
|
|
- Solo 7zr.exe (nessun alias 7z.exe) in C:\polo\scripts\bin\7Zip\
|
|
- Rclone auto, pulizia ZIP, layout bin/conf
|
|
- Schedulazione via schtasks, chiusura console figlie
|
|
#>
|
|
|
|
Add-Type -AssemblyName System.Windows.Forms
|
|
Add-Type -AssemblyName System.Drawing
|
|
Add-Type -AssemblyName System.IO.Compression.FileSystem
|
|
|
|
$ErrorActionPreference = 'Stop'
|
|
|
|
# ------------------------------ HELPERS GRAFICI -------------------------------
|
|
function New-Point([object]$x,[object]$y) { try { return New-Object System.Drawing.Point ([int]$x), ([int]$y) } catch { return [System.Drawing.Point]::new([int]$x, [int]$y) } }
|
|
function New-Size([object]$w,[object]$h) { try { return New-Object System.Drawing.Size ([int]$w), ([int]$h) } catch { return [System.Drawing.Size]::new([int]$w, [int]$h) } }
|
|
function Set-Loc($ctrl,[object]$x,[object]$y){ $ctrl.Location = New-Point $x $y }
|
|
function Set-Sz($ctrl,[object]$w,[object]$h){ $ctrl.Size = New-Size $w $h }
|
|
|
|
# ------------------------------ LOG -------------------------------------------
|
|
function New-LogTimestamp { (Get-Date).ToString('yyyy-MM-dd HH:mm:ss') }
|
|
$global:LogFile = $null
|
|
$global:LogTextBox = $null
|
|
function Write-Log {
|
|
param([Parameter(Mandatory)][string]$Message,[ValidateSet('INFO','ERR','WARN')] [string]$Level = 'INFO')
|
|
$line = "[{0}][{1}] {2}" -f (New-LogTimestamp), $Level, $Message
|
|
if ($global:LogTextBox) { try { $global:LogTextBox.AppendText("$line`r`n") } catch {} }
|
|
if ($global:LogFile) { try { Add-Content -Path $global:LogFile -Value $line -Encoding UTF8 } catch {} }
|
|
Write-Host $line
|
|
}
|
|
|
|
# ------------------------------ UTILS -----------------------------------------
|
|
function Ensure-Dir { param([Parameter(Mandatory)][string]$Path)
|
|
if (-not (Test-Path -LiteralPath $Path)) { New-Item -ItemType Directory -Path $Path | Out-Null; Write-Log "Cartella creata: $Path" }
|
|
else { Write-Log "Cartella già presente: $Path" }
|
|
}
|
|
|
|
function Start-Download {
|
|
param([Parameter(Mandatory)][string]$Url,[Parameter(Mandatory)][string]$Dest)
|
|
Write-Log "Scarico: $Url"; Write-Log "Destinazione: $Dest"
|
|
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 -bor [Net.SecurityProtocolType]::Tls11 -bor [Net.SecurityProtocolType]::Tls
|
|
try {
|
|
Invoke-WebRequest -Uri $Url -OutFile $Dest -ErrorAction Stop
|
|
Write-Log "Download completato."; return $true
|
|
} catch {
|
|
Write-Log "Invoke-WebRequest fallito: $($_.Exception.Message)" 'WARN'
|
|
try { (New-Object System.Net.WebClient).DownloadFile($Url, $Dest); Write-Log "Download completato con WebClient (fallback)."; return $true }
|
|
catch { Write-Log "Download fallito: $($_.Exception.Message)" 'ERR'; return $false }
|
|
}
|
|
}
|
|
|
|
# Estrattore ZIP robusto (overwrite = true) senza usare overload con Encoding
|
|
function Expand-Zip {
|
|
param([Parameter(Mandatory)][string]$ZipPath,[Parameter(Mandatory)][string]$DestDir)
|
|
Write-Log "Estrazione ZIP: $ZipPath -> $DestDir"
|
|
$zip = $null
|
|
try {
|
|
$zip = [System.IO.Compression.ZipFile]::OpenRead($ZipPath)
|
|
foreach ($entry in $zip.Entries) {
|
|
$targetPath = Join-Path $DestDir $entry.FullName
|
|
$targetDir = Split-Path $targetPath -Parent
|
|
if ([string]::IsNullOrEmpty($entry.Name)) {
|
|
Ensure-Dir $targetPath
|
|
} else {
|
|
Ensure-Dir $targetDir
|
|
[System.IO.Compression.ZipFileExtensions]::ExtractToFile($entry, $targetPath, $true)
|
|
}
|
|
}
|
|
} finally {
|
|
if ($zip) { $zip.Dispose() }
|
|
}
|
|
}
|
|
|
|
function New-DailyOrWeeklyTask {
|
|
param([Parameter(Mandatory)][string]$TaskName,
|
|
[Parameter(Mandatory)][string]$ScriptPath,
|
|
[Parameter(Mandatory)][string]$ConfigPath,
|
|
[Parameter(Mandatory)][DateTime]$Time,
|
|
[ValidateSet('DAILY','WEEKLY')] [string]$Schedule = 'DAILY',
|
|
[ValidateSet('MON','TUE','WED','THU','FRI','SAT','SUN')] [string]$Day = 'MON',
|
|
[switch]$Quiet)
|
|
$psArgs = @('-NoProfile','-ExecutionPolicy','Bypass','-File',('"{0}"' -f $ScriptPath),'-Config',('"{0}"' -f $ConfigPath))
|
|
if ($Quiet) { $psArgs += '-Quiet' }
|
|
$tr = 'powershell.exe ' + ($psArgs -join ' ')
|
|
$st = $Time.ToString('HH:mm')
|
|
$cmd = @('/Create','/SC',$Schedule,'/TN',('"{0}"' -f $TaskName),'/TR',('"{0}"' -f $tr),'/ST',$st,'/RL','HIGHEST','/F')
|
|
if ($Schedule -eq 'WEEKLY') { $cmd += @('/D',$Day) }
|
|
Write-Log "Creo/aggiorno attività pianificata: $TaskName ($Schedule) alle $st"
|
|
try { schtasks.exe @cmd | Out-Null; Write-Log "Attività pianificata impostata."; return $true }
|
|
catch { Write-Log "Creazione attività fallita: $($_.Exception.Message)" 'ERR'; return $false }
|
|
}
|
|
|
|
# ------------------------------ LAYOUT BIN/CONF -------------------------------
|
|
function Ensure-ToolsLayout {
|
|
param([Parameter(Mandatory)][string]$Root)
|
|
$binRoot = Join-Path $Root 'bin'
|
|
$confRoot = Join-Path $binRoot 'conf'
|
|
$rcloneDir= Join-Path $binRoot 'RClone'
|
|
$sevenDir = Join-Path $binRoot '7Zip'
|
|
Ensure-Dir $binRoot
|
|
Ensure-Dir $confRoot
|
|
Ensure-Dir $rcloneDir
|
|
Ensure-Dir $sevenDir
|
|
return @{ Bin=$binRoot; Conf=$confRoot; RClone=$rcloneDir; SevenZip=$sevenDir }
|
|
}
|
|
|
|
function Ensure-RcloneExe {
|
|
param([Parameter(Mandatory)][string]$RcloneDir)
|
|
$exe = Join-Path $RcloneDir 'rclone.exe'
|
|
if (-not (Test-Path -LiteralPath $exe)) {
|
|
$zip = Join-Path $RcloneDir 'rclone-current-windows-amd64.zip'
|
|
if (Start-Download -Url 'https://downloads.rclone.org/rclone-current-windows-amd64.zip' -Dest $zip) {
|
|
Expand-Zip -ZipPath $zip -DestDir $RcloneDir
|
|
$found = Get-ChildItem -LiteralPath $RcloneDir -Recurse -Filter 'rclone.exe' | Select-Object -First 1
|
|
if ($found) { Copy-Item -LiteralPath $found.FullName -Destination $exe -Force }
|
|
Get-ChildItem -LiteralPath $RcloneDir -Directory | Where-Object { $_.Name -like 'rclone-*' } | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
|
|
Remove-Item -LiteralPath $zip -Force -ErrorAction SilentlyContinue
|
|
}
|
|
}
|
|
return $exe
|
|
}
|
|
|
|
# === SOLO 7zr.exe =============================================================
|
|
function Ensure-SevenZipExe {
|
|
param([Parameter(Mandatory)][string]$SevenZipDir)
|
|
$exe = Join-Path $SevenZipDir '7zr.exe'
|
|
if (-not (Test-Path -LiteralPath $exe)) {
|
|
$url7zr = 'https://www.7-zip.org/a/7zr.exe'
|
|
if (Start-Download -Url $url7zr -Dest $exe) {
|
|
Write-Log "Installato 7-Zip minimal: $exe"
|
|
} else {
|
|
Write-Log "Impossibile installare 7-Zip (7zr.exe)." 'ERR'
|
|
}
|
|
}
|
|
return $exe
|
|
}
|
|
|
|
# ------------------------------ CONF PARSER -----------------------------------
|
|
$global:ChildPids = New-Object System.Collections.ArrayList
|
|
function Track-Child($p){ if ($p -and $p.Id) { [void]$global:ChildPids.Add($p.Id) } }
|
|
|
|
$global:ConfUi = @{
|
|
Map = [ordered]@{}
|
|
Order = @()
|
|
Controls = @{}
|
|
SourceLines = @()
|
|
TempPath = Join-Path $env:TEMP 'adhoc_backup_conf_preview.conf'
|
|
}
|
|
|
|
function Is-BoolString([string]$s){ if ($null -eq $s) { return $false }
|
|
switch ($s.Trim().ToLowerInvariant()) { 'true' {1};'false' {1};'1' {1};'0' {1};'yes' {1};'no' {1};'y' {1};'n' {1}; default {0} } }
|
|
|
|
function Parse-BackupConf {
|
|
param([Parameter(Mandatory)][string]$Path)
|
|
$order = New-Object System.Collections.ArrayList
|
|
$map = [ordered]@{}
|
|
$lines = Get-Content -LiteralPath $Path -ErrorAction Stop
|
|
foreach ($line in $lines) {
|
|
$trim = $line.Trim()
|
|
if ($trim -eq '' -or $trim.StartsWith('#') -or $trim.StartsWith(';')) { [void]$order.Add(@{type='comment';text=$line}); continue }
|
|
$idx = $trim.IndexOf('='); if ($idx -lt 1) { [void]$order.Add(@{type='raw';text=$line}); continue }
|
|
$k = $trim.Substring(0,$idx).Trim(); $v = $trim.Substring($idx+1).Trim()
|
|
$v = ($v -replace '(\s+)[#;].*$', '').Trim()
|
|
if (($v.StartsWith('"') -and $v.EndsWith('"')) -or ($v.StartsWith("'") -and $v.EndsWith("'"))) { $v = $v.Substring(1,$v.Length-2) }
|
|
$map[$k] = $v; [void]$order.Add(@{type='kv';key=$k})
|
|
}
|
|
$global:ConfUi.Map=$map; $global:ConfUi.Order=$order; $global:ConfUi.SourceLines=$lines
|
|
}
|
|
|
|
function Save-BackupConf { param([Parameter(Mandatory)][string]$Path)
|
|
if (-not $global:ConfUi.Map) { throw "Mappa configurazione non inizializzata." }
|
|
$out = New-Object System.Collections.Generic.List[string]
|
|
foreach ($entry in $global:ConfUi.Order){
|
|
if ($entry.type -eq 'kv'){
|
|
$k=$entry.key; $v=$global:ConfUi.Map[$k]
|
|
if (Is-BoolString $v) { $v = ([string]$v).Trim().ToLowerInvariant(); if ($v -in @('1','yes','y')){$v='true'} elseif ($v -in @('0','no','n')){$v='false'} }
|
|
$out.Add("$k=$v")
|
|
} else { $out.Add($entry.text) }
|
|
}
|
|
foreach ($k in $global:ConfUi.Map.Keys){
|
|
if (-not ($global:ConfUi.Order | Where-Object { $_.type -eq 'kv' -and $_.key -eq $k })) { $out.Add("$k=$($global:ConfUi.Map[$k])") }
|
|
}
|
|
Set-Content -LiteralPath $Path -Value $out -Encoding UTF8
|
|
}
|
|
|
|
# ------------------------------ DEFAULTS --------------------------------------
|
|
$defaultInstall = 'C:\polo\scripts'
|
|
$defaultScriptUrl = 'https://gitea.poloinformatico.it/Mattia/Backup-AdHoc/raw/branch/main/AdHoc-Backup.ps1'
|
|
$defaultConfUrl = 'https://gitea.poloinformatico.it/Mattia/Backup-AdHoc/raw/branch/main/backup.conf'
|
|
|
|
# ------------------------------ UI --------------------------------------------
|
|
$form = New-Object System.Windows.Forms.Form
|
|
$form.Text = 'Installer AdHoc Backup'
|
|
$form.StartPosition = 'CenterScreen'
|
|
$form.MaximizeBox = $true
|
|
$form.FormBorderStyle = 'FixedDialog'
|
|
Set-Sz $form 900 860
|
|
|
|
# Install path
|
|
$lblInstall = New-Object System.Windows.Forms.Label
|
|
$lblInstall.Text = 'Cartella di installazione'; Set-Loc $lblInstall 10 12; Set-Sz $lblInstall 180 20; $form.Controls.Add($lblInstall)
|
|
|
|
$txtInstall = New-Object System.Windows.Forms.TextBox
|
|
Set-Loc $txtInstall 10 32; Set-Sz $txtInstall 760 22; $txtInstall.Text = $defaultInstall; $form.Controls.Add($txtInstall)
|
|
|
|
$btnBrowse = New-Object System.Windows.Forms.Button
|
|
$btnBrowse.Text = 'Scegli...'; Set-Loc $btnBrowse 780 30; Set-Sz $btnBrowse 90 26; $form.Controls.Add($btnBrowse)
|
|
|
|
# URLs
|
|
$lblScriptUrl = New-Object System.Windows.Forms.Label; $lblScriptUrl.Text = 'Script URL'; Set-Loc $lblScriptUrl 10 64; Set-Sz $lblScriptUrl 150 20; $form.Controls.Add($lblScriptUrl)
|
|
$txtScriptUrl = New-Object System.Windows.Forms.TextBox; Set-Loc $txtScriptUrl 10 84; Set-Sz $txtScriptUrl 860 22; $txtScriptUrl.Text = $defaultScriptUrl; $form.Controls.Add($txtScriptUrl)
|
|
|
|
$lblConfUrl = New-Object System.Windows.Forms.Label; $lblConfUrl.Text = 'Config URL'; Set-Loc $lblConfUrl 10 116; Set-Sz $lblConfUrl 150 20; $form.Controls.Add($lblConfUrl)
|
|
$txtConfUrl = New-Object System.Windows.Forms.TextBox; Set-Loc $txtConfUrl 10 136; Set-Sz $txtConfUrl 860 22; $txtConfUrl.Text = $defaultConfUrl; $form.Controls.Add($txtConfUrl)
|
|
|
|
# Opzioni
|
|
$grpOptions = New-Object System.Windows.Forms.GroupBox; $grpOptions.Text = 'Opzioni'; Set-Loc $grpOptions 10 170; Set-Sz $grpOptions 340 120; $form.Controls.Add($grpOptions)
|
|
$chkForceConf = New-Object System.Windows.Forms.CheckBox; $chkForceConf.Text='Sovrascrivi config esistente (ForceConfig)'; Set-Loc $chkForceConf 10 20; Set-Sz $chkForceConf 300 22; $grpOptions.Controls.Add($chkForceConf)
|
|
$chkNoRun = New-Object System.Windows.Forms.CheckBox; $chkNoRun.Text='Non avviare il backup ora (NoRun)'; Set-Loc $chkNoRun 10 45; Set-Sz $chkNoRun 280 22; $grpOptions.Controls.Add($chkNoRun)
|
|
$chkQuiet = New-Object System.Windows.Forms.CheckBox; $chkQuiet.Text='Modalità silenziosa (Quiet)'; Set-Loc $chkQuiet 10 70; Set-Sz $chkQuiet 220 22; $grpOptions.Controls.Add($chkQuiet)
|
|
|
|
# Schedulazione
|
|
$grpSched = New-Object System.Windows.Forms.GroupBox; $grpSched.Text='Schedulazione'; Set-Loc $grpSched 360 170; Set-Sz $grpSched 510 160; $form.Controls.Add($grpSched)
|
|
$chkSchedule = New-Object System.Windows.Forms.CheckBox; $chkSchedule.Text='Crea attività pianificata'; Set-Loc $chkSchedule 10 20; Set-Sz $chkSchedule 200 22; $chkSchedule.Checked=$true; $grpSched.Controls.Add($chkSchedule)
|
|
$lblFreq = New-Object System.Windows.Forms.Label; $lblFreq.Text='Frequenza:'; Set-Loc $lblFreq 20 50; Set-Sz $lblFreq 80 22; $grpSched.Controls.Add($lblFreq)
|
|
$cmbFreq = New-Object System.Windows.Forms.ComboBox; $cmbFreq.DropDownStyle='DropDownList'; [void]$cmbFreq.Items.Add('Giornaliera'); [void]$cmbFreq.Items.Add('Settimanale'); $cmbFreq.SelectedIndex=0; Set-Loc $cmbFreq 100 48; Set-Sz $cmbFreq 120 22; $grpSched.Controls.Add($cmbFreq)
|
|
$lblDOW = New-Object System.Windows.Forms.Label; $lblDOW.Text='Giorno:'; Set-Loc $lblDOW 240 50; Set-Sz $lblDOW 60 22; $grpSched.Controls.Add($lblDOW)
|
|
$cmbDOW = New-Object System.Windows.Forms.ComboBox; $cmbDOW.DropDownStyle='DropDownList'
|
|
'Lunedì (MON)','Martedì (TUE)','Mercoledì (WED)','Giovedì (THU)','Venerdì (FRI)','Sabato (SAT)','Domenica (SUN)' | ForEach-Object { [void]$cmbDOW.Items.Add($_) }
|
|
$cmbDOW.SelectedIndex=0; Set-Loc $cmbDOW 300 48; Set-Sz $cmbDOW 180 22; $cmbDOW.Enabled=$false; $grpSched.Controls.Add($cmbDOW)
|
|
$cmbFreq.Add_SelectedIndexChanged({ $cmbDOW.Enabled = ($cmbFreq.SelectedIndex -eq 1) })
|
|
|
|
$lblTime = New-Object System.Windows.Forms.Label; $lblTime.Text='Ora:'; Set-Loc $lblTime 20 85; Set-Sz $lblTime 40 22; $grpSched.Controls.Add($lblTime)
|
|
$timePicker = New-Object System.Windows.Forms.DateTimePicker; $timePicker.Format=[System.Windows.Forms.DateTimePickerFormat]::Time; $timePicker.ShowUpDown=$true
|
|
$tpDefault = Get-Date; $tpDefault = Get-Date -Hour 23 -Minute 0 -Second 0
|
|
$timePicker.Value = $tpDefault; Set-Loc $timePicker 60 82; Set-Sz $timePicker 100 22; $grpSched.Controls.Add($timePicker)
|
|
|
|
$lblTask = New-Object System.Windows.Forms.Label; $lblTask.Text='Nome task:'; Set-Loc $lblTask 180 85; Set-Sz $lblTask 80 22; $grpSched.Controls.Add($lblTask)
|
|
$txtTask = New-Object System.Windows.Forms.TextBox; Set-Loc $txtTask 260 82; Set-Sz $txtTask 230 22; $txtTask.Text='Backup_AdHoc'; $grpSched.Controls.Add($txtTask)
|
|
|
|
# Argomenti extra
|
|
$lblExtra = New-Object System.Windows.Forms.Label; $lblExtra.Text='Argomenti extra per AdHoc (es. -WhatIf)'; Set-Loc $lblExtra 10 340; Set-Sz $lblExtra 380 20; $form.Controls.Add($lblExtra)
|
|
$txtExtra = New-Object System.Windows.Forms.TextBox; Set-Loc $txtExtra 10 362; Set-Sz $txtExtra 860 22; $form.Controls.Add($txtExtra)
|
|
|
|
# ------------------------------ TAB: CONFIGURAZIONE ---------------------------
|
|
$tabs = New-Object System.Windows.Forms.TabControl; Set-Loc $tabs 10 392; Set-Sz $tabs 860 230; $form.Controls.Add($tabs)
|
|
$tabConfig = New-Object System.Windows.Forms.TabPage; $tabConfig.Text='Configurazione (backup.conf)'; [void]$tabs.TabPages.Add($tabConfig)
|
|
|
|
$cfgPanel = New-Object System.Windows.Forms.Panel; Set-Loc $cfgPanel 10 10; Set-Sz $cfgPanel 830 150; $cfgPanel.AutoScroll=$true; $tabConfig.Controls.Add($cfgPanel)
|
|
|
|
$btnReloadConf = New-Object System.Windows.Forms.Button; $btnReloadConf.Text='Ricarica da URL'; Set-Loc $btnReloadConf 10 170; Set-Sz $btnReloadConf 120 26; $tabConfig.Controls.Add($btnReloadConf)
|
|
$btnSaveConf = New-Object System.Windows.Forms.Button; $btnSaveConf.Text='Salva in bin\\conf'; Set-Loc $btnSaveConf 140 170; Set-Sz $btnSaveConf 230 26; $tabConfig.Controls.Add($btnSaveConf)
|
|
$btnRcloneConfig = New-Object System.Windows.Forms.Button; $btnRcloneConfig.Text='Configura rclone (console)'; Set-Loc $btnRcloneConfig 380 170; Set-Sz $btnRcloneConfig 170 26; $tabConfig.Controls.Add($btnRcloneConfig)
|
|
|
|
function Build-ConfigUI {
|
|
$cfgPanel.Controls.Clear(); $global:ConfUi.Controls = @{}
|
|
$xLabel=10; $xCtrl=260; $y=10; $h=24
|
|
foreach ($k in $global:ConfUi.Map.Keys) {
|
|
$key = [string]$k # copia locale e forte tipizzazione
|
|
$v = $global:ConfUi.Map[$key]
|
|
$lbl = New-Object System.Windows.Forms.Label; $lbl.Text=$key; $lbl.Tag=$key; Set-Loc $lbl $xLabel ($y+4); Set-Sz $lbl 240 $h; $cfgPanel.Controls.Add($lbl)
|
|
if (Is-BoolString $v) {
|
|
$chk = New-Object System.Windows.Forms.CheckBox
|
|
$chk.Tag = $key
|
|
$chk.Checked = (('1','true','yes','y') -contains ($v.ToString().ToLower()))
|
|
Set-Loc $chk $xCtrl ($y+2); Set-Sz $chk 20 $h
|
|
$chk.add_CheckedChanged({ param($sender,$args)
|
|
try {
|
|
$k2 = [string]$sender.Tag
|
|
if (-not [string]::IsNullOrEmpty($k2)) {
|
|
$global:ConfUi.Map[$k2] = if ($sender.Checked) { 'true' } else { 'false' }
|
|
}
|
|
} catch { Write-Log "Update booleano fallito: $($_.Exception.Message)" 'WARN' }
|
|
})
|
|
$cfgPanel.Controls.Add($chk); $global:ConfUi.Controls[$key]=$chk
|
|
} else {
|
|
$tb = New-Object System.Windows.Forms.TextBox
|
|
$tb.Tag = $key
|
|
$tb.Text=$v; Set-Loc $tb $xCtrl $y; Set-Sz $tb 540 $h
|
|
$tb.add_TextChanged({ param($sender,$args)
|
|
try {
|
|
$k2 = [string]$sender.Tag
|
|
if (-not [string]::IsNullOrEmpty($k2)) {
|
|
$global:ConfUi.Map[$k2] = $sender.Text
|
|
}
|
|
} catch { Write-Log "Update testo fallito: $($_.Exception.Message)" 'WARN' }
|
|
})
|
|
$cfgPanel.Controls.Add($tb); $global:ConfUi.Controls[$key]=$tb
|
|
}
|
|
$y += 28
|
|
}
|
|
}
|
|
|
|
$btnReloadConf.Add_Click({
|
|
try {
|
|
$temp = $global:ConfUi.TempPath
|
|
if (Start-Download -Url $txtConfUrl.Text -Dest $temp) {
|
|
Parse-BackupConf -Path $temp; Build-ConfigUI; Write-Log "backup.conf scaricato e caricato in editor: $temp"
|
|
}
|
|
} catch { Write-Log "Errore ricarica backup.conf: $($_.Exception.Message)" 'ERR' }
|
|
})
|
|
|
|
$btnSaveConf.Add_Click({
|
|
try {
|
|
$layout = Ensure-ToolsLayout -Root $txtInstall.Text
|
|
$dest = Join-Path $layout.Conf 'backup.conf'
|
|
Save-BackupConf -Path $dest
|
|
Write-Log "backup.conf salvato in: $dest"
|
|
} catch { Write-Log "Errore salvataggio backup.conf: $($_.Exception.Message)" 'ERR' }
|
|
})
|
|
|
|
# Avvio rclone config in console dedicata
|
|
$btnRcloneConfig.Add_Click({
|
|
try {
|
|
$layout = Ensure-ToolsLayout -Root $txtInstall.Text
|
|
$rcloneExe = Ensure-RcloneExe -RcloneDir $layout.RClone
|
|
$rcloneConf = Join-Path $layout.Conf 'rclone.conf'
|
|
$p = Start-Process -FilePath $rcloneExe -ArgumentList @('config','--config', $rcloneConf) -WorkingDirectory $layout.RClone -PassThru
|
|
Track-Child $p
|
|
Write-Log "Avviato rclone config (PID=$($p.Id))"
|
|
} catch { Write-Log "Errore avvio rclone config: $($_.Exception.Message)" 'ERR' }
|
|
})
|
|
|
|
# ------------------------------ BOTTONI AZIONE --------------------------------
|
|
$btnInstall = New-Object System.Windows.Forms.Button; $btnInstall.Text='Installa'; Set-Loc $btnInstall 10 652; Set-Sz $btnInstall 120 30; $form.Controls.Add($btnInstall)
|
|
$btnClose = New-Object System.Windows.Forms.Button; $btnClose.Text='Chiudi'; Set-Loc $btnClose 150 652; Set-Sz $btnClose 120 30; $form.Controls.Add($btnClose)
|
|
|
|
# LOG
|
|
$lblLog = New-Object System.Windows.Forms.Label; $lblLog.Text='Log'; Set-Loc $lblLog 10 692; Set-Sz $lblLog 50 20; $form.Controls.Add($lblLog)
|
|
$txtLog = New-Object System.Windows.Forms.TextBox; Set-Loc $txtLog 10 712; Set-Sz $txtLog 860 100; $txtLog.Multiline=$true; $txtLog.ScrollBars='Vertical'; $txtLog.ReadOnly=$true; $form.Controls.Add($txtLog); $global:LogTextBox = $txtLog
|
|
|
|
# ------------------------------ HANDLERS --------------------------------------
|
|
$btnBrowse.Add_Click({ $dlg = New-Object System.Windows.Forms.FolderBrowserDialog; $dlg.Description='Seleziona cartella di installazione'; if ($dlg.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK){ $txtInstall.Text=$dlg.SelectedPath } })
|
|
|
|
$btnInstall.Add_Click({
|
|
try {
|
|
$btnInstall.Enabled = $false
|
|
$root = $txtInstall.Text; Ensure-Dir $root
|
|
$layout = Ensure-ToolsLayout -Root $root
|
|
|
|
# Scarica/installa Rclone e SOLO 7zr.exe
|
|
$rcloneExe = Ensure-RcloneExe -RcloneDir $layout.RClone
|
|
if (-not (Test-Path -LiteralPath $rcloneExe)) { Write-Log "ATTENZIONE: rclone.exe non installato." 'WARN' }
|
|
$sevenExe = Ensure-SevenZipExe -SevenZipDir $layout.SevenZip
|
|
if (-not (Test-Path -LiteralPath $sevenExe)) { Write-Log "ATTENZIONE: 7-Zip (7zr.exe) non installato." 'WARN' }
|
|
|
|
# Script principale
|
|
$scriptPath = Join-Path $root 'AdHoc-Backup.ps1'
|
|
if (-not (Start-Download -Url $txtScriptUrl.Text -Dest $scriptPath)) { throw "Impossibile scaricare lo script principale." }
|
|
|
|
# backup.conf -> bin\conf\backup.conf
|
|
$confPath = Join-Path $layout.Conf 'backup.conf'
|
|
if ($global:ConfUi.Map) { Save-BackupConf -Path $confPath }
|
|
else {
|
|
if (-not (Start-Download -Url $txtConfUrl.Text -Dest $confPath)) { Write-Log "Attenzione: impossibile ottenere backup.conf; procedo senza." 'WARN' }
|
|
}
|
|
|
|
# Schedulazione
|
|
if ($chkSchedule.Checked) {
|
|
$schedule = if ($cmbFreq.SelectedIndex -eq 1) { 'WEEKLY' } else { 'DAILY' }
|
|
$dowmap = @('MON','TUE','WED','THU','FRI','SAT','SUN'); $day=$dowmap[0]; if ($schedule -eq 'WEEKLY'){ $day=$dowmap[$cmbDOW.SelectedIndex] }
|
|
[void](New-DailyOrWeeklyTask -TaskName $txtTask.Text -ScriptPath $scriptPath -ConfigPath $confPath -Time $timePicker.Value -Schedule $schedule -Day $day -Quiet:$chkQuiet.Checked)
|
|
}
|
|
|
|
# Avvio immediato
|
|
if (-not $chkNoRun.Checked) {
|
|
$args=@('-NoProfile','-ExecutionPolicy','Bypass','-File',"`"$scriptPath`"","-Config", "`"$confPath`"")
|
|
if ($chkQuiet.Checked){ $args += '-Quiet' }
|
|
if ($txtExtra.Text -and $txtExtra.Text.Trim() -ne ''){ $args += $txtExtra.Text.Trim().Split(' ') }
|
|
$p=Start-Process -FilePath 'powershell.exe' -ArgumentList $args -PassThru; Track-Child $p; Write-Log "Esecuzione avviata (PID=$($p.Id))."
|
|
}
|
|
|
|
Write-Log "Installazione completata."
|
|
} catch { Write-Log "Errore durante l'installazione: $($_.Exception.Message)" 'ERR' }
|
|
finally { $btnInstall.Enabled = $true }
|
|
})
|
|
|
|
$btnClose.Add_Click({ $form.Close() })
|
|
|
|
# Evita conflitto con variabile automatica $PID
|
|
$form.Add_FormClosed({
|
|
foreach ($cpid in $global:ChildPids) {
|
|
try {
|
|
$proc = Get-Process -Id $cpid -ErrorAction SilentlyContinue
|
|
if ($proc) {
|
|
$null = $proc.CloseMainWindow()
|
|
Start-Sleep -Milliseconds 200
|
|
if (-not $proc.HasExited) { Stop-Process -Id $cpid -Force -ErrorAction SilentlyContinue }
|
|
}
|
|
} catch {}
|
|
}
|
|
})
|
|
|
|
# ------------------------------ AVVIO -----------------------------------------
|
|
$global:LogFile = Join-Path $env:TEMP "install-adhoc-backup_gui_$(Get-Date -Format 'yyyyMMdd_HHmmss').log"
|
|
Write-Log "Log file: $global:LogFile"
|
|
|
|
try {
|
|
$temp = $global:ConfUi.TempPath
|
|
if (Start-Download -Url $defaultConfUrl -Dest $temp) { Parse-BackupConf -Path $temp; Build-ConfigUI; Write-Log "backup.conf iniziale caricato da: $defaultConfUrl" }
|
|
else { Write-Log "Non sono riuscito a scaricare il backup.conf iniziale." 'WARN' }
|
|
} catch { Write-Log "Errore iniziale confer: $($_.Exception.Message)" 'ERR' }
|
|
|
|
[void]$form.ShowDialog()
|