diff --git a/WinToolkit-template.ps1 b/WinToolkit-template.ps1 index 6b1f73a..c51403c 100644 --- a/WinToolkit-template.ps1 +++ b/WinToolkit-template.ps1 @@ -1585,6 +1585,87 @@ function WinUpdateReset {} function WinReinstallStore {} function WinBackupDriver {} function WinDriverInstall {} +# ============================================================================ +# OFFICE: Funzioni helper condivise (Install / Repair / Uninstall) +# ============================================================================ +function Invoke-OfficeSilentRemoval { + param([Parameter(Mandatory = $true)][string]$Path, [switch]$Recurse) + if (-not (Test-Path $Path)) { return $false } + try { + $params = @{ Path = $Path; Force = $true; ErrorAction = 'SilentlyContinue' } + if ($Recurse) { $params['Recurse'] = $true } + Remove-Item @params *>$null + Clear-ProgressLine + return $true + } catch { return $false } +} + +function Stop-OfficeProcesses { + $processes = @('winword', 'excel', 'powerpnt', 'outlook', 'onenote', 'msaccess', 'visio', 'lync') + $closed = 0 + Write-StyledMessage -Type 'Info' -Text "πŸ“‹ Chiusura processi Office." + foreach ($processName in $processes) { + $running = Get-Process -Name $processName -ErrorAction SilentlyContinue + if ($running) { + try { $running | Stop-Process -Force -ErrorAction Stop; $closed++ } + catch { Write-StyledMessage -Type 'Warning' -Text "Impossibile chiudere: $processName." } + } + } + if ($closed -gt 0) { Write-StyledMessage -Type 'Success' -Text "$closed processi Office chiusi." } +} + +function Invoke-OfficeDownloadFile([string]$Url, [string]$OutputPath, [string]$Description) { + try { + Write-StyledMessage -Type 'Info' -Text "πŸ“₯ Download $Description." + $webClient = New-Object System.Net.WebClient + $webClient.DownloadFile($Url, $OutputPath) + $webClient.Dispose() + $success = (Test-Path $OutputPath) + Write-StyledMessage -Type ($success ? 'Success' : 'Error') -Text ($success ? "Download completato: $Description" : "File non trovato dopo download: $Description.") + return $success + } + catch { + Write-StyledMessage -Type 'Error' -Text "Errore download $Description`: $_" + return $false + } +} + +function Set-OfficePostConfig { + Write-StyledMessage -Type 'Info' -Text "βš™οΈ Ottimizzazione profonda di Microsoft Office." + + $registrySettings = @( + # Privacy & Telemetria + @{ Path = "HKCU:\SOFTWARE\Policies\Microsoft\office\16.0\common"; Name = "sendtelemetry"; Value = 0 }, + @{ Path = "HKLM:\SOFTWARE\Policies\Microsoft\office\16.0\common"; Name = "sendtelemetry"; Value = 0 }, + @{ Path = "HKCU:\SOFTWARE\Policies\Microsoft\office\16.0\common\privacy"; Name = "disconnectedstate"; Value = 1 }, + @{ Path = "HKCU:\SOFTWARE\Policies\Microsoft\office\16.0\common\privacy"; Name = "usercontentdisabled"; Value = 1 }, + @{ Path = "HKCU:\SOFTWARE\Policies\Microsoft\office\16.0\common\privacy"; Name = "downloadcontentdisabled"; Value = 1 }, + @{ Path = "HKCU:\SOFTWARE\Microsoft\Office\16.0\Common\General"; Name = "ShownOptIn"; Value = 1 }, + @{ Path = "HKCU:\SOFTWARE\Microsoft\Office\16.0\Common\Feedback"; Name = "Enabled"; Value = 0 }, + # Performance & UI + @{ Path = "HKCU:\SOFTWARE\Microsoft\Office\16.0\Common\Graphics"; Name = "DisableAnimations"; Value = 1 }, + @{ Path = "HKCU:\SOFTWARE\Microsoft\Office\16.0\Common\Graphics"; Name = "DisableHardwareAcceleration"; Value = 1 }, + @{ Path = "HKCU:\SOFTWARE\Microsoft\Office\16.0\Common\General"; Name = "DisableBootToStartScreen"; Value = 1 }, + @{ Path = "HKCU:\SOFTWARE\Microsoft\Office\16.0\Common\LinkedIn"; Name = "ShowLinkedInIntegration"; Value = 0 } + ) + + foreach ($reg in $registrySettings) { + if (-not (Test-Path $reg.Path)) { $null = New-Item -Path $reg.Path -Force } + Set-ItemProperty -Path $reg.Path -Name $reg.Name -Value $reg.Value -Type 'DWord' -Force + } + + $tasksToDisable = @( + "OfficeTelemetryAgentLogon", "OfficeTelemetryAgentFallback", + "OfficeBackgroundTaskHandlerRegistration", "OfficeBackgroundTaskHandlerLogon", + "OfficeFeatureUpdates", "OfficeFeatureUpdatesLogon" + ) + foreach ($tName in $tasksToDisable) { + Get-ScheduledTask | Where-Object { $_.TaskName -eq $tName } | Disable-ScheduledTask -ErrorAction SilentlyContinue + } + + Write-StyledMessage -Type 'Success' -Text "βœ… Office ottimizzato: telemetria, privacy e task pianificati rimossi." +} + function Install-Office {} function Repair-Office {} function Uninstall-Office {} diff --git a/WinToolkit.ps1 b/WinToolkit.ps1 index 320457b..152871a 100644 --- a/WinToolkit.ps1 +++ b/WinToolkit.ps1 @@ -67,7 +67,7 @@ function Read-Host { } $ErrorActionPreference = 'Stop' try { $Host.UI.RawUI.WindowTitle = "WinToolkit by MagnetarMan" } catch {} -$ToolkitVersion = "2.5.4 (Build 44)" +$ToolkitVersion = "Sviluppo in Corso" $AppConfig = @{ URLs = @{ GitHubAssetBaseUrl = "https://raw.githubusercontent.com/Magnetarman/WinToolkit/refs/heads/main/asset/" @@ -2425,6 +2425,74 @@ function WinBackupDriver { } } function WinDriverInstall {} +function Invoke-OfficeSilentRemoval { + param([Parameter(Mandatory = $true)][string]$Path, [switch]$Recurse) + if (-not (Test-Path $Path)) { return $false } + try { + $params = @{ Path = $Path; Force = $true; ErrorAction = 'SilentlyContinue' } + if ($Recurse) { $params['Recurse'] = $true } + Remove-Item @params *>$null + Clear-ProgressLine + return $true + } catch { return $false } +} +function Stop-OfficeProcesses { + $processes = @('winword', 'excel', 'powerpnt', 'outlook', 'onenote', 'msaccess', 'visio', 'lync') + $closed = 0 + Write-StyledMessage -Type 'Info' -Text "πŸ“‹ Chiusura processi Office." + foreach ($processName in $processes) { + $running = Get-Process -Name $processName -ErrorAction SilentlyContinue + if ($running) { + try { $running | Stop-Process -Force -ErrorAction Stop; $closed++ } + catch { Write-StyledMessage -Type 'Warning' -Text "Impossibile chiudere: $processName." } + } + } + if ($closed -gt 0) { Write-StyledMessage -Type 'Success' -Text "$closed processi Office chiusi." } +} +function Invoke-OfficeDownloadFile([string]$Url, [string]$OutputPath, [string]$Description) { + try { + Write-StyledMessage -Type 'Info' -Text "πŸ“₯ Download $Description." + $webClient = New-Object System.Net.WebClient + $webClient.DownloadFile($Url, $OutputPath) + $webClient.Dispose() + $success = (Test-Path $OutputPath) + Write-StyledMessage -Type ($success ? 'Success' : 'Error') -Text ($success ? "Download completato: $Description" : "File non trovato dopo download: $Description.") + return $success + } + catch { + Write-StyledMessage -Type 'Error' -Text "Errore download $Description`: $_" + return $false + } +} +function Set-OfficePostConfig { + Write-StyledMessage -Type 'Info' -Text "βš™οΈ Ottimizzazione profonda di Microsoft Office." + $registrySettings = @( + @{ Path = "HKCU:\SOFTWARE\Policies\Microsoft\office\16.0\common"; Name = "sendtelemetry"; Value = 0 }, + @{ Path = "HKLM:\SOFTWARE\Policies\Microsoft\office\16.0\common"; Name = "sendtelemetry"; Value = 0 }, + @{ Path = "HKCU:\SOFTWARE\Policies\Microsoft\office\16.0\common\privacy"; Name = "disconnectedstate"; Value = 1 }, + @{ Path = "HKCU:\SOFTWARE\Policies\Microsoft\office\16.0\common\privacy"; Name = "usercontentdisabled"; Value = 1 }, + @{ Path = "HKCU:\SOFTWARE\Policies\Microsoft\office\16.0\common\privacy"; Name = "downloadcontentdisabled"; Value = 1 }, + @{ Path = "HKCU:\SOFTWARE\Microsoft\Office\16.0\Common\General"; Name = "ShownOptIn"; Value = 1 }, + @{ Path = "HKCU:\SOFTWARE\Microsoft\Office\16.0\Common\Feedback"; Name = "Enabled"; Value = 0 }, + @{ Path = "HKCU:\SOFTWARE\Microsoft\Office\16.0\Common\Graphics"; Name = "DisableAnimations"; Value = 1 }, + @{ Path = "HKCU:\SOFTWARE\Microsoft\Office\16.0\Common\Graphics"; Name = "DisableHardwareAcceleration"; Value = 1 }, + @{ Path = "HKCU:\SOFTWARE\Microsoft\Office\16.0\Common\General"; Name = "DisableBootToStartScreen"; Value = 1 }, + @{ Path = "HKCU:\SOFTWARE\Microsoft\Office\16.0\Common\LinkedIn"; Name = "ShowLinkedInIntegration"; Value = 0 } + ) + foreach ($reg in $registrySettings) { + if (-not (Test-Path $reg.Path)) { $null = New-Item -Path $reg.Path -Force } + Set-ItemProperty -Path $reg.Path -Name $reg.Name -Value $reg.Value -Type 'DWord' -Force + } + $tasksToDisable = @( + "OfficeTelemetryAgentLogon", "OfficeTelemetryAgentFallback", + "OfficeBackgroundTaskHandlerRegistration", "OfficeBackgroundTaskHandlerLogon", + "OfficeFeatureUpdates", "OfficeFeatureUpdatesLogon" + ) + foreach ($tName in $tasksToDisable) { + Get-ScheduledTask | Where-Object { $_.TaskName -eq $tName } | Disable-ScheduledTask -ErrorAction SilentlyContinue + } + Write-StyledMessage -Type 'Success' -Text "βœ… Office ottimizzato: telemetria, privacy e task pianificati rimossi." +} function Install-Office { [CmdletBinding()] param( @@ -2435,53 +2503,6 @@ function Install-Office { Show-Header -SubTitle "Office Install" $Host.UI.RawUI.WindowTitle = "Office Install By MagnetarMan" $tempDir = $AppConfig.Paths.OfficeTemp - function Invoke-SilentRemoval { - param( - [Parameter(Mandatory = $true)][string]$Path, - [switch]$Recurse - ) - if (-not (Test-Path $Path)) { return $false } - try { - $params = @{ Path = $Path; Force = $true; ErrorAction = 'SilentlyContinue' } - if ($Recurse) { $params['Recurse'] = $true } - Remove-Item @params *>$null - Clear-ProgressLine - return $true - } catch { return $false } - } - function Apply-OfficePostConfig { - Write-StyledMessage -Type 'Info' -Text "βš™οΈ Configurazione post-installazione Office." - $telemetryKeys = @( - @{ Path = "HKCU:\SOFTWARE\Policies\Microsoft\office\16.0\common"; Name = "sendtelemetry"; Value = 0 }, - @{ Path = "HKCU:\SOFTWARE\Policies\Microsoft\office\16.0\common\privacy"; Name = "disconnectedstate"; Value = 1 }, - @{ Path = "HKCU:\SOFTWARE\Policies\Microsoft\office\16.0\common\privacy"; Name = "usercontentdisabled"; Value = 1 }, - @{ Path = "HKCU:\SOFTWARE\Policies\Microsoft\office\16.0\common\privacy"; Name = "downloadcontentdisabled"; Value = 1 }, - @{ Path = "HKLM:\SOFTWARE\Policies\Microsoft\office\16.0\common"; Name = "sendtelemetry"; Value = 0 } - ) - foreach ($reg in $telemetryKeys) { - if (-not (Test-Path $reg.Path)) { $null = New-Item -Path $reg.Path -Force } - Set-ItemProperty -Path $reg.Path -Name $reg.Name -Value $reg.Value -Type 'DWord' -Force - } - $feedbackPath = "HKCU:\SOFTWARE\Microsoft\Office\16.0\Common\General" - if (-not (Test-Path $feedbackPath)) { $null = New-Item $feedbackPath -Force } - Set-ItemProperty -Path $feedbackPath -Name "ShownOptIn" -Value 1 -Type 'DWord' -Force - Write-StyledMessage -Type 'Success' -Text "βœ… Telemetria e Privacy Office disabilitate." - } - function Invoke-DownloadFile([string]$Url, [string]$OutputPath, [string]$Description) { - try { - Write-StyledMessage -Type 'Info' -Text "πŸ“₯ Download $Description." - $webClient = New-Object System.Net.WebClient - $webClient.DownloadFile($Url, $OutputPath) - $webClient.Dispose() - $success = (Test-Path $OutputPath) - Write-StyledMessage -Type ($success ? 'Success' : 'Error') -Text ($success ? "Download completato: $Description" : "File non trovato dopo download: $Description.") - return $success - } - catch { - Write-StyledMessage -Type 'Error' -Text "Errore download $Description`: $_" - return $false - } - } try { Write-StyledMessage -Type 'Info' -Text "🏒 Avvio installazione Office Basic." if (-not (Test-Path $tempDir)) { $null = New-Item -ItemType Directory -Path $tempDir -Force } @@ -2492,7 +2513,7 @@ function Install-Office { @{ Url = $AppConfig.URLs.OfficeBasicConfig; Path = $configPath; Name = 'Configurazione Basic' } ) foreach ($dl in $downloads) { - if (-not (Invoke-DownloadFile $dl.Url $dl.Path $dl.Name)) { + if (-not (Invoke-OfficeDownloadFile $dl.Url $dl.Path $dl.Name)) { Write-StyledMessage -Type 'Error' -Text "Download fallito. Installazione annullata." return } @@ -2505,7 +2526,7 @@ function Install-Office { Write-StyledMessage -Type 'Error' -Text "Installazione fallita." return } - Apply-OfficePostConfig + Set-OfficePostConfig Write-StyledMessage -Type 'Success' -Text "βœ… Installazione completata." Write-StyledMessage -Type 'Info' -Text "Riavvio non necessario." } @@ -2518,7 +2539,7 @@ function Install-Office { } } finally { - Invoke-SilentRemoval -Path $tempDir -Recurse + Invoke-OfficeSilentRemoval -Path $tempDir -Recurse Write-StyledMessage -Type 'Success' -Text "🎯 Office Install terminato." Write-ToolkitLog -Level INFO -Message "Install-Office sessione terminata." } @@ -2532,56 +2553,6 @@ function Repair-Office { Start-ToolkitLog -ToolName "OfficeRepair" Show-Header -SubTitle "Office Repair" $Host.UI.RawUI.WindowTitle = "Office Repair By MagnetarMan" - function Invoke-SilentRemoval { - param( - [Parameter(Mandatory = $true)][string]$Path, - [switch]$Recurse - ) - if (-not (Test-Path $Path)) { return $false } - try { - $params = @{ Path = $Path; Force = $true; ErrorAction = 'SilentlyContinue' } - if ($Recurse) { $params['Recurse'] = $true } - Remove-Item @params *>$null - Clear-ProgressLine - return $true - } catch { return $false } - } - function Stop-OfficeProcesses { - $processes = @('winword', 'excel', 'powerpnt', 'outlook', 'onenote', 'msaccess', 'visio', 'lync') - $closed = 0 - Write-StyledMessage -Type 'Info' -Text "πŸ“‹ Chiusura processi Office." - foreach ($processName in $processes) { - $running = Get-Process -Name $processName -ErrorAction SilentlyContinue - if ($running) { - try { - $running | Stop-Process -Force -ErrorAction Stop - $closed++ - } - catch { - Write-StyledMessage -Type 'Warning' -Text "Impossibile chiudere: $processName." - } - } - } - if ($closed -gt 0) { Write-StyledMessage -Type 'Success' -Text "$closed processi Office chiusi." } - } - function Apply-OfficePostConfig { - Write-StyledMessage -Type 'Info' -Text "βš™οΈ Configurazione post-riparazione Office." - $telemetryKeys = @( - @{ Path = "HKCU:\SOFTWARE\Policies\Microsoft\office\16.0\common"; Name = "sendtelemetry"; Value = 0 }, - @{ Path = "HKCU:\SOFTWARE\Policies\Microsoft\office\16.0\common\privacy"; Name = "disconnectedstate"; Value = 1 }, - @{ Path = "HKCU:\SOFTWARE\Policies\Microsoft\office\16.0\common\privacy"; Name = "usercontentdisabled"; Value = 1 }, - @{ Path = "HKCU:\SOFTWARE\Policies\Microsoft\office\16.0\common\privacy"; Name = "downloadcontentdisabled"; Value = 1 }, - @{ Path = "HKLM:\SOFTWARE\Policies\Microsoft\office\16.0\common"; Name = "sendtelemetry"; Value = 0 } - ) - foreach ($reg in $telemetryKeys) { - if (-not (Test-Path $reg.Path)) { $null = New-Item -Path $reg.Path -Force } - Set-ItemProperty -Path $reg.Path -Name $reg.Name -Value $reg.Value -Type 'DWord' -Force - } - $feedbackPath = "HKCU:\SOFTWARE\Microsoft\Office\16.0\Common\General" - if (-not (Test-Path $feedbackPath)) { $null = New-Item $feedbackPath -Force } - Set-ItemProperty -Path $feedbackPath -Name "ShownOptIn" -Value 1 -Type 'DWord' -Force - Write-StyledMessage -Type 'Success' -Text "βœ… Telemetria e Privacy Office disabilitate." - } $needsReboot = $false try { Write-StyledMessage -Type 'Info' -Text "πŸ”§ Avvio riparazione Office." @@ -2593,7 +2564,7 @@ function Repair-Office { ) $cleanedCount = 0 foreach ($cache in $caches) { - if (Invoke-SilentRemoval -Path $cache -Recurse) { $cleanedCount++ } + if (Invoke-OfficeSilentRemoval -Path $cache -Recurse) { $cleanedCount++ } } if ($cleanedCount -gt 0) { Write-StyledMessage -Type 'Success' -Text "$cleanedCount cache eliminate." } $officeClient = (Test-Path "${env:ProgramFiles}\Common Files\microsoft shared\ClickToRun\OfficeClickToRun.exe") ? @@ -2608,7 +2579,7 @@ function Repair-Office { $null = Invoke-WithSpinner -Activity "Riparazione Rapida Office (Offline)" -Command $officeClient ` -Arguments "scenario=Repair platform=x64 culture=it-it forceappshutdown=True RepairType=QuickRepair DisplayLevel=True" ` -TimeoutSeconds 86400 -LogContextKey "Office-Repair-Quick" - Apply-OfficePostConfig + Set-OfficePostConfig Write-StyledMessage -Type 'Success' -Text "πŸŽ‰ Riparazione Office completata!" $needsReboot = $true } @@ -2619,7 +2590,7 @@ function Repair-Office { $null = Invoke-WithSpinner -Activity "Riparazione Completa Office (Online)" -Command $officeClient ` -Arguments "scenario=Repair platform=x64 culture=it-it forceappshutdown=True RepairType=FullRepair DisplayLevel=True" ` -TimeoutSeconds 86400 -LogContextKey "Office-Repair-Full" - Apply-OfficePostConfig + Set-OfficePostConfig Write-StyledMessage -Type 'Success' -Text "πŸŽ‰ Riparazione Office completata!" $needsReboot = $true } @@ -2662,38 +2633,6 @@ function Uninstall-Office { Show-Header -SubTitle "Office Uninstall" $Host.UI.RawUI.WindowTitle = "Office Uninstall By MagnetarMan" $tempDir = $AppConfig.Paths.OfficeTemp - function Invoke-SilentRemoval { - param( - [Parameter(Mandatory = $true)][string]$Path, - [switch]$Recurse - ) - if (-not (Test-Path $Path)) { return $false } - try { - $params = @{ Path = $Path; Force = $true; ErrorAction = 'SilentlyContinue' } - if ($Recurse) { $params['Recurse'] = $true } - Remove-Item @params *>$null - Clear-ProgressLine - return $true - } catch { return $false } - } - function Stop-OfficeProcesses { - $processes = @('winword', 'excel', 'powerpnt', 'outlook', 'onenote', 'msaccess', 'visio', 'lync') - $closed = 0 - Write-StyledMessage -Type 'Info' -Text "πŸ“‹ Chiusura processi Office." - foreach ($processName in $processes) { - $running = Get-Process -Name $processName -ErrorAction SilentlyContinue - if ($running) { - try { - $running | Stop-Process -Force -ErrorAction Stop - $closed++ - } - catch { - Write-StyledMessage -Type 'Warning' -Text "Impossibile chiudere: $processName." - } - } - } - if ($closed -gt 0) { Write-StyledMessage -Type 'Success' -Text "$closed processi Office chiusi." } - } function Get-WindowsVersion { try { $buildNumber = [int](Get-CimInstance -ClassName Win32_OperatingSystem).BuildNumber @@ -2704,6 +2643,18 @@ function Uninstall-Office { return "Unknown" } } + function Remove-ItemsSilently { + param([string[]]$Paths, [string]$ItemType = "cartella") + $removed = @() + $failed = @() + foreach ($path in $Paths) { + if (Test-Path $path) { + if (Invoke-OfficeSilentRemoval -Path $path -Recurse) { $removed += $path } + else { $failed += $path } + } + } + return @{ Removed = $removed; Failed = $failed; Count = $removed.Count } + } function Invoke-DownloadFile([string]$Url, [string]$OutputPath, [string]$Description) { try { Write-StyledMessage -Type 'Info' -Text "πŸ“₯ Download $Description." @@ -2841,7 +2792,7 @@ function Uninstall-Office { foreach ($shortcut in $officeShortcuts) { $shortcutFiles = Get-ChildItem -Path $desktopPath -Filter $shortcut -Recurse -ErrorAction SilentlyContinue foreach ($file in $shortcutFiles) { - if (Invoke-SilentRemoval -Path $file.FullName) { $shortcutsRemoved++ } + if (Invoke-OfficeSilentRemoval -Path $file.FullName) { $shortcutsRemoved++ } } } } @@ -2867,7 +2818,7 @@ function Uninstall-Office { try { if (-not (Test-Path $tempDir)) { $null = New-Item -ItemType Directory -Path $tempDir -Force } $getHelpZipPath = Join-Path $tempDir 'GetHelp.zip' - if (-not (Invoke-DownloadFile $AppConfig.URLs.GetHelpInstaller $getHelpZipPath 'Microsoft Get Help')) { + if (-not (Invoke-OfficeDownloadFile $AppConfig.URLs.GetHelpInstaller $getHelpZipPath 'Microsoft Get Help')) { return $false } Write-StyledMessage -Type 'Info' -Text "πŸ“¦ Estrazione Get Help." @@ -2899,12 +2850,11 @@ function Uninstall-Office { if (Get-Process -Name $blockingProcesses -ErrorAction SilentlyContinue) { Write-StyledMessage -Type 'Info' -Text "⏳ Get Help ha avviato la rimozione in una finestra esterna." Write-StyledMessage -Type 'Info' -Text " Il Toolkit rimarrΓ  in attesa fino alla chiusura del processo di rimozione..." - $spinnerIndex = 0 - while ((Get-Process -Name $blockingProcesses -ErrorAction SilentlyContinue) -and ((Get-Date) - $waitStart).TotalSeconds -lt 2700) { - $elapsed = [math]::Round(((Get-Date) - $waitStart).TotalSeconds, 1) - $spinner = if ($Global:Spinners) { $Global:Spinners[$spinnerIndex++ % $Global:Spinners.Length] } else { '' } - Show-ProgressBar -Activity "Rimozione Office" -Status "In corso in finestra esterna... ($elapsed secondi)" -Percent 90 -Icon '⏳' -Spinner $spinner - Start-Sleep -Milliseconds 500 + while ((Get-Process -Name $blockingProcesses -ErrorAction SilentlyContinue) -and ((Get-Date) - $waitStart).TotalMinutes -lt 45) { + $elapsed = [math]::Round(((Get-Date) - $waitStart).TotalMinutes, 1) + $spinner = if ($Global:Spinners) { $Global:Spinners[(Get-Date).Millisecond % $Global:Spinners.Length] } else { '' } + Show-ProgressBar -Activity "Rimozione Office" -Status "In corso in finestra esterna... ($elapsed min)" -Percent 90 -Icon '⏳' -Spinner $spinner + Start-Sleep -Seconds 5 } Clear-ProgressLine } @@ -2929,7 +2879,7 @@ function Uninstall-Office { return $false } finally { - Invoke-SilentRemoval -Path $tempDir -Recurse + Invoke-OfficeSilentRemoval -Path $tempDir -Recurse } } $needsReboot = $false @@ -2971,7 +2921,7 @@ function Uninstall-Office { } finally { Write-StyledMessage -Type 'Success' -Text "🧹 Pulizia finale." - Invoke-SilentRemoval -Path $tempDir -Recurse + Invoke-OfficeSilentRemoval -Path $tempDir -Recurse Write-StyledMessage -Type 'Success' -Text "🎯 Office Uninstall terminato." Write-ToolkitLog -Level INFO -Message "Uninstall-Office sessione terminata." } diff --git a/tool/Install-Office.ps1 b/tool/Install-Office.ps1 index b059a7b..f200e10 100644 --- a/tool/Install-Office.ps1 +++ b/tool/Install-Office.ps1 @@ -17,60 +17,6 @@ function Install-Office { $tempDir = $AppConfig.Paths.OfficeTemp - function Invoke-SilentRemoval { - param( - [Parameter(Mandatory = $true)][string]$Path, - [switch]$Recurse - ) - if (-not (Test-Path $Path)) { return $false } - try { - $params = @{ Path = $Path; Force = $true; ErrorAction = 'SilentlyContinue' } - if ($Recurse) { $params['Recurse'] = $true } - Remove-Item @params *>$null - Clear-ProgressLine - return $true - } catch { return $false } - } - - function Apply-OfficePostConfig { - Write-StyledMessage -Type 'Info' -Text "βš™οΈ Configurazione post-installazione Office." - - $telemetryKeys = @( - @{ Path = "HKCU:\SOFTWARE\Policies\Microsoft\office\16.0\common"; Name = "sendtelemetry"; Value = 0 }, - @{ Path = "HKCU:\SOFTWARE\Policies\Microsoft\office\16.0\common\privacy"; Name = "disconnectedstate"; Value = 1 }, - @{ Path = "HKCU:\SOFTWARE\Policies\Microsoft\office\16.0\common\privacy"; Name = "usercontentdisabled"; Value = 1 }, - @{ Path = "HKCU:\SOFTWARE\Policies\Microsoft\office\16.0\common\privacy"; Name = "downloadcontentdisabled"; Value = 1 }, - @{ Path = "HKLM:\SOFTWARE\Policies\Microsoft\office\16.0\common"; Name = "sendtelemetry"; Value = 0 } - ) - - foreach ($reg in $telemetryKeys) { - if (-not (Test-Path $reg.Path)) { $null = New-Item -Path $reg.Path -Force } - Set-ItemProperty -Path $reg.Path -Name $reg.Name -Value $reg.Value -Type 'DWord' -Force - } - - $feedbackPath = "HKCU:\SOFTWARE\Microsoft\Office\16.0\Common\General" - if (-not (Test-Path $feedbackPath)) { $null = New-Item $feedbackPath -Force } - Set-ItemProperty -Path $feedbackPath -Name "ShownOptIn" -Value 1 -Type 'DWord' -Force - - Write-StyledMessage -Type 'Success' -Text "βœ… Telemetria e Privacy Office disabilitate." - } - - function Invoke-DownloadFile([string]$Url, [string]$OutputPath, [string]$Description) { - try { - Write-StyledMessage -Type 'Info' -Text "πŸ“₯ Download $Description." - $webClient = New-Object System.Net.WebClient - $webClient.DownloadFile($Url, $OutputPath) - $webClient.Dispose() - $success = (Test-Path $OutputPath) - Write-StyledMessage -Type ($success ? 'Success' : 'Error') -Text ($success ? "Download completato: $Description" : "File non trovato dopo download: $Description.") - return $success - } - catch { - Write-StyledMessage -Type 'Error' -Text "Errore download $Description`: $_" - return $false - } - } - try { Write-StyledMessage -Type 'Info' -Text "🏒 Avvio installazione Office Basic." @@ -85,7 +31,7 @@ function Install-Office { ) foreach ($dl in $downloads) { - if (-not (Invoke-DownloadFile $dl.Url $dl.Path $dl.Name)) { + if (-not (Invoke-OfficeDownloadFile $dl.Url $dl.Path $dl.Name)) { Write-StyledMessage -Type 'Error' -Text "Download fallito. Installazione annullata." return } @@ -102,7 +48,7 @@ function Install-Office { return } - Apply-OfficePostConfig + Set-OfficePostConfig Write-StyledMessage -Type 'Success' -Text "βœ… Installazione completata." Write-StyledMessage -Type 'Info' -Text "Riavvio non necessario." } @@ -115,7 +61,7 @@ function Install-Office { } } finally { - Invoke-SilentRemoval -Path $tempDir -Recurse + Invoke-OfficeSilentRemoval -Path $tempDir -Recurse Write-StyledMessage -Type 'Success' -Text "🎯 Office Install terminato." Write-ToolkitLog -Level INFO -Message "Install-Office sessione terminata." } diff --git a/tool/Repair-Office.ps1 b/tool/Repair-Office.ps1 index ba7979b..9ac12ba 100644 --- a/tool/Repair-Office.ps1 +++ b/tool/Repair-Office.ps1 @@ -15,64 +15,6 @@ function Repair-Office { Show-Header -SubTitle "Office Repair" $Host.UI.RawUI.WindowTitle = "Office Repair By MagnetarMan" - function Invoke-SilentRemoval { - param( - [Parameter(Mandatory = $true)][string]$Path, - [switch]$Recurse - ) - if (-not (Test-Path $Path)) { return $false } - try { - $params = @{ Path = $Path; Force = $true; ErrorAction = 'SilentlyContinue' } - if ($Recurse) { $params['Recurse'] = $true } - Remove-Item @params *>$null - Clear-ProgressLine - return $true - } catch { return $false } - } - - function Stop-OfficeProcesses { - $processes = @('winword', 'excel', 'powerpnt', 'outlook', 'onenote', 'msaccess', 'visio', 'lync') - $closed = 0 - - Write-StyledMessage -Type 'Info' -Text "πŸ“‹ Chiusura processi Office." - foreach ($processName in $processes) { - $running = Get-Process -Name $processName -ErrorAction SilentlyContinue - if ($running) { - try { - $running | Stop-Process -Force -ErrorAction Stop - $closed++ - } - catch { - Write-StyledMessage -Type 'Warning' -Text "Impossibile chiudere: $processName." - } - } - } - if ($closed -gt 0) { Write-StyledMessage -Type 'Success' -Text "$closed processi Office chiusi." } - } - - function Apply-OfficePostConfig { - Write-StyledMessage -Type 'Info' -Text "βš™οΈ Configurazione post-riparazione Office." - - $telemetryKeys = @( - @{ Path = "HKCU:\SOFTWARE\Policies\Microsoft\office\16.0\common"; Name = "sendtelemetry"; Value = 0 }, - @{ Path = "HKCU:\SOFTWARE\Policies\Microsoft\office\16.0\common\privacy"; Name = "disconnectedstate"; Value = 1 }, - @{ Path = "HKCU:\SOFTWARE\Policies\Microsoft\office\16.0\common\privacy"; Name = "usercontentdisabled"; Value = 1 }, - @{ Path = "HKCU:\SOFTWARE\Policies\Microsoft\office\16.0\common\privacy"; Name = "downloadcontentdisabled"; Value = 1 }, - @{ Path = "HKLM:\SOFTWARE\Policies\Microsoft\office\16.0\common"; Name = "sendtelemetry"; Value = 0 } - ) - - foreach ($reg in $telemetryKeys) { - if (-not (Test-Path $reg.Path)) { $null = New-Item -Path $reg.Path -Force } - Set-ItemProperty -Path $reg.Path -Name $reg.Name -Value $reg.Value -Type 'DWord' -Force - } - - $feedbackPath = "HKCU:\SOFTWARE\Microsoft\Office\16.0\Common\General" - if (-not (Test-Path $feedbackPath)) { $null = New-Item $feedbackPath -Force } - Set-ItemProperty -Path $feedbackPath -Name "ShownOptIn" -Value 1 -Type 'DWord' -Force - - Write-StyledMessage -Type 'Success' -Text "βœ… Telemetria e Privacy Office disabilitate." - } - $needsReboot = $false try { @@ -86,7 +28,7 @@ function Repair-Office { ) $cleanedCount = 0 foreach ($cache in $caches) { - if (Invoke-SilentRemoval -Path $cache -Recurse) { $cleanedCount++ } + if (Invoke-OfficeSilentRemoval -Path $cache -Recurse) { $cleanedCount++ } } if ($cleanedCount -gt 0) { Write-StyledMessage -Type 'Success' -Text "$cleanedCount cache eliminate." } @@ -105,7 +47,7 @@ function Repair-Office { -Arguments "scenario=Repair platform=x64 culture=it-it forceappshutdown=True RepairType=QuickRepair DisplayLevel=True" ` -TimeoutSeconds 86400 -LogContextKey "Office-Repair-Quick" - Apply-OfficePostConfig + Set-OfficePostConfig Write-StyledMessage -Type 'Success' -Text "πŸŽ‰ Riparazione Office completata!" $needsReboot = $true } @@ -117,7 +59,7 @@ function Repair-Office { -Arguments "scenario=Repair platform=x64 culture=it-it forceappshutdown=True RepairType=FullRepair DisplayLevel=True" ` -TimeoutSeconds 86400 -LogContextKey "Office-Repair-Full" - Apply-OfficePostConfig + Set-OfficePostConfig Write-StyledMessage -Type 'Success' -Text "πŸŽ‰ Riparazione Office completata!" $needsReboot = $true } diff --git a/tool/Uninstall-Office.ps1 b/tool/Uninstall-Office.ps1 index da968d0..4a58841 100644 --- a/tool/Uninstall-Office.ps1 +++ b/tool/Uninstall-Office.ps1 @@ -18,44 +18,9 @@ function Uninstall-Office { $tempDir = $AppConfig.Paths.OfficeTemp # ============================================================================ - # FUNZIONI HELPER + # FUNZIONI HELPER SPECIFICHE PER UNINSTALL # ============================================================================ - function Invoke-SilentRemoval { - param( - [Parameter(Mandatory = $true)][string]$Path, - [switch]$Recurse - ) - if (-not (Test-Path $Path)) { return $false } - try { - $params = @{ Path = $Path; Force = $true; ErrorAction = 'SilentlyContinue' } - if ($Recurse) { $params['Recurse'] = $true } - Remove-Item @params *>$null - Clear-ProgressLine - return $true - } catch { return $false } - } - - function Stop-OfficeProcesses { - $processes = @('winword', 'excel', 'powerpnt', 'outlook', 'onenote', 'msaccess', 'visio', 'lync') - $closed = 0 - - Write-StyledMessage -Type 'Info' -Text "πŸ“‹ Chiusura processi Office." - foreach ($processName in $processes) { - $running = Get-Process -Name $processName -ErrorAction SilentlyContinue - if ($running) { - try { - $running | Stop-Process -Force -ErrorAction Stop - $closed++ - } - catch { - Write-StyledMessage -Type 'Warning' -Text "Impossibile chiudere: $processName." - } - } - } - if ($closed -gt 0) { Write-StyledMessage -Type 'Success' -Text "$closed processi Office chiusi." } - } - function Get-WindowsVersion { try { $buildNumber = [int](Get-CimInstance -ClassName Win32_OperatingSystem).BuildNumber @@ -67,29 +32,13 @@ function Uninstall-Office { } } - function Invoke-DownloadFile([string]$Url, [string]$OutputPath, [string]$Description) { - try { - Write-StyledMessage -Type 'Info' -Text "πŸ“₯ Download $Description." - $webClient = New-Object System.Net.WebClient - $webClient.DownloadFile($Url, $OutputPath) - $webClient.Dispose() - $success = (Test-Path $OutputPath) - Write-StyledMessage -Type ($success ? 'Success' : 'Error') -Text ($success ? "Download completato: $Description" : "File non trovato dopo download: $Description.") - return $success - } - catch { - Write-StyledMessage -Type 'Error' -Text "Errore download $Description`: $_" - return $false - } - } - function Remove-ItemsSilently { param([string[]]$Paths, [string]$ItemType = "cartella") $removed = @() $failed = @() foreach ($path in $Paths) { if (Test-Path $path) { - if (Invoke-SilentRemoval -Path $path -Recurse) { $removed += $path } + if (Invoke-OfficeSilentRemoval -Path $path -Recurse) { $removed += $path } else { $failed += $path } } } @@ -218,7 +167,7 @@ function Uninstall-Office { foreach ($shortcut in $officeShortcuts) { $shortcutFiles = Get-ChildItem -Path $desktopPath -Filter $shortcut -Recurse -ErrorAction SilentlyContinue foreach ($file in $shortcutFiles) { - if (Invoke-SilentRemoval -Path $file.FullName) { $shortcutsRemoved++ } + if (Invoke-OfficeSilentRemoval -Path $file.FullName) { $shortcutsRemoved++ } } } } @@ -248,7 +197,7 @@ function Uninstall-Office { if (-not (Test-Path $tempDir)) { $null = New-Item -ItemType Directory -Path $tempDir -Force } $getHelpZipPath = Join-Path $tempDir 'GetHelp.zip' - if (-not (Invoke-DownloadFile $AppConfig.URLs.GetHelpInstaller $getHelpZipPath 'Microsoft Get Help')) { + if (-not (Invoke-OfficeDownloadFile $AppConfig.URLs.GetHelpInstaller $getHelpZipPath 'Microsoft Get Help')) { return $false } @@ -276,28 +225,24 @@ function Uninstall-Office { -Arguments '-S OfficeScrubScenario -AcceptEula' ` -TimeoutSeconds 86400 -LogContextKey "Office-Uninstall-GetHelp" - # Verifica se l'output contiene errori o il menu di aiuto (segno di parametri errati) $outputStr = $result.StdOut + $result.StdErr $isInvalidArgs = $outputStr -match "Error: Invalid command line arguments" -or $outputStr -match "Usage: GetHelpCmd\.exe" if ($result.ExitCode -eq 0 -and -not $isInvalidArgs) { - # Attendere che i processi esterni (Setup, SaRA, etc.) terminino davvero $blockingProcesses = @('Setup', 'SaRACmd', 'Microsoft.Support.Recovery.Assistant.App', 'OfficeClickToRun', 'Integrator', 'GetHelpCmd', 'OfficeScrub', 'cscript') $waitStart = Get-Date - - # Breve attesa per permettere lo spawn del processo esterno + Start-Sleep -Seconds 12 - + if (Get-Process -Name $blockingProcesses -ErrorAction SilentlyContinue) { Write-StyledMessage -Type 'Info' -Text "⏳ Get Help ha avviato la rimozione in una finestra esterna." Write-StyledMessage -Type 'Info' -Text " Il Toolkit rimarrΓ  in attesa fino alla chiusura del processo di rimozione..." - - $spinnerIndex = 0 - while ((Get-Process -Name $blockingProcesses -ErrorAction SilentlyContinue) -and ((Get-Date) - $waitStart).TotalSeconds -lt 2700) { - $elapsed = [math]::Round(((Get-Date) - $waitStart).TotalSeconds, 1) - $spinner = if ($Global:Spinners) { $Global:Spinners[$spinnerIndex++ % $Global:Spinners.Length] } else { '' } - Show-ProgressBar -Activity "Rimozione Office" -Status "In corso in finestra esterna... ($elapsed secondi)" -Percent 90 -Icon '⏳' -Spinner $spinner - Start-Sleep -Milliseconds 500 + + while ((Get-Process -Name $blockingProcesses -ErrorAction SilentlyContinue) -and ((Get-Date) - $waitStart).TotalMinutes -lt 45) { + $elapsed = [math]::Round(((Get-Date) - $waitStart).TotalMinutes, 1) + $spinner = if ($Global:Spinners) { $Global:Spinners[(Get-Date).Millisecond % $Global:Spinners.Length] } else { '' } + Show-ProgressBar -Activity "Rimozione Office" -Status "In corso in finestra esterna... ($elapsed min)" -Percent 90 -Icon '⏳' -Spinner $spinner + Start-Sleep -Seconds 5 } Clear-ProgressLine } @@ -323,7 +268,7 @@ function Uninstall-Office { return $false } finally { - Invoke-SilentRemoval -Path $tempDir -Recurse + Invoke-OfficeSilentRemoval -Path $tempDir -Recurse } } @@ -375,7 +320,7 @@ function Uninstall-Office { } finally { Write-StyledMessage -Type 'Success' -Text "🧹 Pulizia finale." - Invoke-SilentRemoval -Path $tempDir -Recurse + Invoke-OfficeSilentRemoval -Path $tempDir -Recurse Write-StyledMessage -Type 'Success' -Text "🎯 Office Uninstall terminato." Write-ToolkitLog -Level INFO -Message "Uninstall-Office sessione terminata." }