From 88b5f1b6295c5ec3101d21c7b3ffe98842fcc69d Mon Sep 17 00:00:00 2001 From: Jeffrey <9938813+Raphire@users.noreply.github.com> Date: Tue, 23 Jun 2026 01:04:29 +0200 Subject: [PATCH] Store user data (backups, logs, settings) under LocalAppData, update start menu backup creation --- Run.bat | 4 +- Scripts/Features/ReplaceStartMenu.ps1 | 47 ++++++++++++----------- Scripts/GUI/Show-MainWindow.ps1 | 2 +- Scripts/GUI/Show-RestoreBackupDialog.ps1 | 49 +++--------------------- Scripts/GUI/Show-RestoreBackupWindow.ps1 | 3 +- Scripts/Get-Dev.ps1 | 41 ++------------------ Scripts/Get.ps1 | 41 ++------------------ Win11Debloat.ps1 | 8 ++-- 8 files changed, 46 insertions(+), 149 deletions(-) diff --git a/Run.bat b/Run.bat index 396d4f1..94ab225 100644 --- a/Run.bat +++ b/Run.bat @@ -4,10 +4,10 @@ setlocal EnableDelayedExpansion :: Set Windows Terminal installation paths. (Default and Scoop installation) set "wtDefaultPath=%LOCALAPPDATA%\Microsoft\WindowsApps\wt.exe" set "wtScoopPath=%USERPROFILE%\scoop\apps\windows-terminal\current\wt.exe" -set "logFile=%~dp0Logs\Win11Debloat-Run.log" +set "logFile=%LOCALAPPDATA%\Win11Debloat\Logs\Win11Debloat-Run.log" :: Ensure Logs folder exists -if not exist "%~dp0Logs" mkdir "%~dp0Logs" +if not exist "%LOCALAPPDATA%\Win11Debloat\Logs" mkdir "%LOCALAPPDATA%\Win11Debloat\Logs" :: Determine which terminal exists if exist "%wtDefaultPath%" ( diff --git a/Scripts/Features/ReplaceStartMenu.ps1 b/Scripts/Features/ReplaceStartMenu.ps1 index 89bd47e..6c3eb8b 100644 --- a/Scripts/Features/ReplaceStartMenu.ps1 +++ b/Scripts/Features/ReplaceStartMenu.ps1 @@ -113,7 +113,12 @@ function ReplaceStartMenu { return } - $backupBinFile = $startMenuBinFile + ".bak" + $startMenuBackupsDir = Join-Path $script:AppDataPath 'Backups' + if (-not (Test-Path $startMenuBackupsDir)) { + New-Item -ItemType Directory -Path $startMenuBackupsDir -Force | Out-Null + } + $backupTimestamp = (Get-Date).ToString('yyyyMMdd_HHmmss') + $backupBinFile = Join-Path $startMenuBackupsDir "Win11Debloat-Start2BinBackup-$userName-$backupTimestamp.bak" if (Test-Path $startMenuBinFile) { # Backup current start menu file @@ -221,16 +226,18 @@ function RestoreStartMenuFromBackup { ) $userName = GetStartMenuUserNameFromPath -StartMenuBinFile $StartMenuBinFile + $backupTimestamp = (Get-Date).ToString('yyyyMMdd_HHmmss') + $startMenuBackupsDir = Join-Path $script:AppDataPath 'Backups' $backupBinFile = if ([string]::IsNullOrWhiteSpace($BackupFilePath)) { - $StartMenuBinFile + '.bak' + Join-Path $startMenuBackupsDir "Win11Debloat-Start2BinBackup-$userName-$backupTimestamp.bak" } else { $BackupFilePath } - $currentBinBackup = $StartMenuBinFile + '.restore.bak' + $currentBinBackup = Join-Path $startMenuBackupsDir "Win11Debloat-Start2BinRestore-$userName-$backupTimestamp.bak" if ($script:Params.ContainsKey("WhatIf")) { - Write-Host "[WhatIf] Restore start menu for user $userName from backup $backupBinFile" -ForegroundColor Cyan + Write-Host "[WhatIf] Restore start menu for user $userName from backup $BackupFilePath" -ForegroundColor Cyan return [PSCustomObject]@{ UserName = $userName Result = $true @@ -238,11 +245,11 @@ function RestoreStartMenuFromBackup { } } - if (-not (Test-Path -LiteralPath $backupBinFile)) { + if (-not (Test-Path -LiteralPath $BackupFilePath)) { return [PSCustomObject]@{ UserName = $userName Result = $false - Message = "No start menu backup file found for user $userName." + Message = "Start menu backup file not found: $BackupFilePath" } } @@ -251,7 +258,7 @@ function RestoreStartMenuFromBackup { Move-Item -Path $StartMenuBinFile -Destination $currentBinBackup -Force } - Copy-Item -Path $backupBinFile -Destination $StartMenuBinFile -Force + Copy-Item -Path $BackupFilePath -Destination $StartMenuBinFile -Force return [PSCustomObject]@{ UserName = $userName Result = $true @@ -278,17 +285,14 @@ function RestoreStartMenuFromBackup { be resolved. .PARAMETER BackupFilePath - Path to the backup file to restore from. If omitted, defaults to - the .bak file alongside the current start2.bin. + Path to the backup file to restore from. .EXAMPLE - RestoreStartMenu - - .EXAMPLE - RestoreStartMenu -BackupFilePath "C:\Backups\start2.bin" + RestoreStartMenu -BackupFilePath "$env:LOCALAPPDATA\Win11Debloat\Backups\Win11Debloat-Start2BinBackup-Jeff-20260623_143000.bak" #> function RestoreStartMenu { param( + [Parameter(Mandatory)] [string]$BackupFilePath ) @@ -315,22 +319,19 @@ function RestoreStartMenu { .DESCRIPTION Iterates over every existing user profile and restores each user's - start2.bin from its .bak backup. For the Default user profile, removes - the start2.bin file (which was previously copied from a template) so - that new profiles revert to the system default start menu. + start2.bin from the specified backup file. For the Default user profile, + removes the start2.bin file (which was previously copied from a template) + so that new profiles revert to the system default start menu. .PARAMETER BackupFilePath - Path to the backup file to restore from. If omitted, defaults to - the .bak file alongside each user's current start2.bin. + Path to the backup file to restore from. .EXAMPLE - RestoreStartMenuForAllUsers - - .EXAMPLE - RestoreStartMenuForAllUsers -BackupFilePath "C:\Backups\start2.bin" + RestoreStartMenuForAllUsers -BackupFilePath "$env:LOCALAPPDATA\Win11Debloat\Backups\Win11Debloat-Start2BinBackup-Jeff-20260623_143000.bak" #> -function RestoreStartMenuForAllUsers { +function RestoreStartMenuForAllUsers { param( + [Parameter(Mandatory)] [string]$BackupFilePath ) diff --git a/Scripts/GUI/Show-MainWindow.ps1 b/Scripts/GUI/Show-MainWindow.ps1 index 7e3b3ff..bd683d8 100644 --- a/Scripts/GUI/Show-MainWindow.ps1 +++ b/Scripts/GUI/Show-MainWindow.ps1 @@ -159,7 +159,7 @@ $menuReportBug.Add_Click({ Start-Process "https://github.com/Raphire/Win11Debloat/issues" }) $menuLogs.Add_Click({ - $logsFolder = Join-Path (Split-Path (Split-Path $PSScriptRoot -Parent) -Parent) 'Logs' + $logsFolder = Split-Path $script:DefaultLogPath -Parent if (Test-Path $logsFolder) { Start-Process "explorer.exe" -ArgumentList $logsFolder } diff --git a/Scripts/GUI/Show-RestoreBackupDialog.ps1 b/Scripts/GUI/Show-RestoreBackupDialog.ps1 index 0b6f0f0..3936578 100644 --- a/Scripts/GUI/Show-RestoreBackupDialog.ps1 +++ b/Scripts/GUI/Show-RestoreBackupDialog.ps1 @@ -61,6 +61,7 @@ function Show-RestoreBackupDialog { $startMenuIntroPanel = $window.FindName('StartMenuIntroPanel') $startMenuScopeCombo = $window.FindName('StartMenuScopeCombo') $startMenuAutoBackupCheck = $window.FindName('StartMenuAutoBackupCheck') + $startMenuAutoBackupCheck.Visibility = 'Collapsed' $introInfoPanel = $window.FindName('IntroInfoPanel') $overviewPanel = $window.FindName('OverviewPanel') $overviewFeaturesSection = $window.FindName('OverviewFeaturesSection') @@ -148,9 +149,8 @@ function Show-RestoreBackupDialog { return } - $isAutoBackupEnabled = ($startMenuAutoBackupCheck.IsChecked -eq $true) - $hasSelectedManualFile = -not [string]::IsNullOrWhiteSpace($state.SelectedStartMenuBackupFilePath) - if ($isAutoBackupEnabled -or $hasSelectedManualFile) { + $hasSelectedFile = -not [string]::IsNullOrWhiteSpace($state.SelectedStartMenuBackupFilePath) + if ($hasSelectedFile) { $primaryActionBtn.Content = 'Restore backup' } else { @@ -302,15 +302,11 @@ function Show-RestoreBackupDialog { } $handleStartMenuPrimaryAction = { - $scope = (& $getStartMenuScopeInfo).Scope - $useManualBackupFile = -not ($startMenuAutoBackupCheck.IsChecked -eq $true) - - if ($useManualBackupFile -and [string]::IsNullOrWhiteSpace($state.SelectedStartMenuBackupFilePath)) { + if ([string]::IsNullOrWhiteSpace($state.SelectedStartMenuBackupFilePath)) { $openDialog = New-Object Microsoft.Win32.OpenFileDialog $openDialog.Title = 'Select Start Menu Backup File' $openDialog.Filter = 'Start Menu backup (*.bak)|*.bak' - $openDialog.InitialDirectory = "$env:LOCALAPPDATA\Packages\Microsoft.Windows.StartMenuExperienceHost_cw5n1h2txyewy\LocalState" - $openDialog.DefaultExt = '.bak' + $openDialog.InitialDirectory = (Join-Path $script:AppDataPath 'Backups') if ($openDialog.ShowDialog($window) -ne $true) { return @@ -322,34 +318,10 @@ function Show-RestoreBackupDialog { return } - if (-not $useManualBackupFile) { - $autoBackupExists = $false - if ($scope -eq 'AllUsers') { - $userPathString = GetUserDirectory -userName "*" -fileName "AppData\Local\Packages\Microsoft.Windows.StartMenuExperienceHost_cw5n1h2txyewy\LocalState" - $usersStartMenuPaths = Get-ChildItem -Path $userPathString -ErrorAction SilentlyContinue - foreach ($startMenuPath in $usersStartMenuPaths) { - if (Test-Path -LiteralPath (Join-Path $startMenuPath.FullName 'start2.bin.bak')) { - $autoBackupExists = $true - break - } - } - } - else { - $autoBackupPath = "$env:LOCALAPPDATA\Packages\Microsoft.Windows.StartMenuExperienceHost_cw5n1h2txyewy\LocalState\start2.bin.bak" - $autoBackupExists = Test-Path -LiteralPath $autoBackupPath - } - - if (-not $autoBackupExists) { - $scopeText = (& $getStartMenuScopeInfo).SummaryText - Show-MessageBox -Owner $window -Title 'No Backup Found' -Message "No Start Menu backup file was found. You can uncheck the 'Automatically find Start Menu backup' option to select a backup file manually." -Button 'OK' -Icon 'Warning' | Out-Null - return - } - } - + $scope = (& $getStartMenuScopeInfo).Scope $window.Tag = @{ Result = 'RestoreStartMenu' StartMenuScope = $scope - UseManualBackupFile = $useManualBackupFile BackupFilePath = $state.SelectedStartMenuBackupFilePath } $window.DialogResult = $true @@ -368,14 +340,6 @@ function Show-RestoreBackupDialog { } } - $startMenuAutoBackupCheck.Add_Checked({ - $state.SelectedStartMenuBackupFilePath = $null - & $refreshStartMenuUi - }) - $startMenuAutoBackupCheck.Add_Unchecked({ - & $refreshStartMenuUi - }) - $startMenuScopeCombo.Add_SelectionChanged({ & $refreshStartMenuUi }) @@ -410,7 +374,6 @@ function Show-RestoreBackupDialog { if ($state.WizardStep -eq 'StartMenu') { $state.SelectedStartMenuBackupFilePath = $null - $startMenuAutoBackupCheck.IsChecked = $true } & $setWizardStep 'SelectType' diff --git a/Scripts/GUI/Show-RestoreBackupWindow.ps1 b/Scripts/GUI/Show-RestoreBackupWindow.ps1 index f8e0995..a71a2f2 100644 --- a/Scripts/GUI/Show-RestoreBackupWindow.ps1 +++ b/Scripts/GUI/Show-RestoreBackupWindow.ps1 @@ -40,7 +40,6 @@ function Show-RestoreBackupWindow { } elseif ($dialogResult.Result -eq 'RestoreStartMenu') { $scope = $dialogResult.StartMenuScope - $useManualBackupFile = ($dialogResult.UseManualBackupFile -eq $true) $backupFilePath = $null if ($dialogResult -is [hashtable] -and $dialogResult.ContainsKey('BackupFilePath')) { $backupFilePath = $dialogResult['BackupFilePath'] @@ -49,7 +48,7 @@ function Show-RestoreBackupWindow { $backupFilePath = $dialogResult.BackupFilePath } - if ($useManualBackupFile -and [string]::IsNullOrWhiteSpace($backupFilePath)) { + if ([string]::IsNullOrWhiteSpace($backupFilePath)) { throw 'Start Menu restore canceled: no backup file selected.' } diff --git a/Scripts/Get-Dev.ps1 b/Scripts/Get-Dev.ps1 index b8a2e9c..c067eb0 100644 --- a/Scripts/Get-Dev.ps1 +++ b/Scripts/Get-Dev.ps1 @@ -131,31 +131,12 @@ catch { Exit } -# Remove old script folder if it exists, but keep configs, logs and backups +# Remove old script folder if it exists if (Test-Path $tempWorkPath) { Write-Output "" Write-Output "> Cleaning up old Win11Debloat folder..." - Get-ChildItem -Path $tempWorkPath -Exclude Config,Logs,Backups | Remove-Item -Recurse -Force -} - -$configDir = Join-Path $tempWorkPath 'Config' -$backupDir = Join-Path $tempWorkPath 'ConfigOld' - -# Temporarily move existing config files if they exist to prevent them from being overwritten by the new script files, will be moved back after the new script is unpacked -if (Test-Path "$configDir") { - Write-Output "" - Write-Output "> Backing up existing config files..." - - New-Item -ItemType Directory -Path "$backupDir" -Force | Out-Null - - $filesToKeep = @( - 'LastUsedSettings.json' - ) - - Get-ChildItem -Path "$configDir" -Recurse | Where-Object { $_.Name -in $filesToKeep } | Move-Item -Destination "$backupDir" - - Remove-Item "$configDir" -Recurse -Force + Remove-Item $tempWorkPath -Recurse -Force } Write-Output "" @@ -170,19 +151,6 @@ Remove-Item $tempArchivePath # Move files Get-ChildItem -Path (Join-Path $tempWorkPath '*Win11Debloat-*') -Recurse | Move-Item -Destination $tempWorkPath -# Add existing config files back to Config folder -if (Test-Path "$backupDir") { - if (-not (Test-Path "$configDir")) { - New-Item -ItemType Directory -Path "$configDir" -Force | Out-Null - } - - Write-Output "" - Write-Output "> Restoring existing config files..." - - Get-ChildItem -Path "$backupDir" -Recurse | Move-Item -Destination "$configDir" - Remove-Item "$backupDir" -Recurse -Force -} - # Make list of arguments to pass on to the script $arguments = $($PSBoundParameters.GetEnumerator() | ForEach-Object { if ($_.Value -eq $true) { @@ -219,13 +187,12 @@ if ($null -ne $debloatProcess) { $debloatProcess.WaitForExit() } -# Remove all remaining script files, except for configs, logs and backups +# Remove all remaining script files if (Test-Path $tempWorkPath) { Write-Output "" Write-Output "> Cleaning up..." - # Cleanup, remove Win11Debloat directory - Get-ChildItem -Path $tempWorkPath -Exclude Config,Logs,Backups | Remove-Item -Recurse -Force + Remove-Item $tempWorkPath -Recurse -Force } Write-Output "" diff --git a/Scripts/Get.ps1 b/Scripts/Get.ps1 index 012cb89..bdf1783 100644 --- a/Scripts/Get.ps1 +++ b/Scripts/Get.ps1 @@ -132,31 +132,12 @@ catch { Exit } -# Remove old script folder if it exists, but keep configs, logs and backups +# Remove old script folder if it exists if (Test-Path $tempWorkPath) { Write-Output "" Write-Output "> Cleaning up old Win11Debloat folder..." - Get-ChildItem -Path $tempWorkPath -Exclude Config,Logs,Backups | Remove-Item -Recurse -Force -} - -$configDir = Join-Path $tempWorkPath 'Config' -$backupDir = Join-Path $tempWorkPath 'ConfigOld' - -# Temporarily move existing config files if they exist to prevent them from being overwritten by the new script files, will be moved back after the new script is unpacked -if (Test-Path "$configDir") { - Write-Output "" - Write-Output "> Backing up existing config files..." - - New-Item -ItemType Directory -Path "$backupDir" -Force | Out-Null - - $filesToKeep = @( - 'LastUsedSettings.json' - ) - - Get-ChildItem -Path "$configDir" -Recurse | Where-Object { $_.Name -in $filesToKeep } | Move-Item -Destination "$backupDir" - - Remove-Item "$configDir" -Recurse -Force + Remove-Item $tempWorkPath -Recurse -Force } Write-Output "" @@ -171,19 +152,6 @@ Remove-Item $tempArchivePath # Move files Get-ChildItem -Path (Join-Path $tempWorkPath '*Win11Debloat-*') -Recurse | Move-Item -Destination $tempWorkPath -# Add existing config files back to Config folder -if (Test-Path "$backupDir") { - if (-not (Test-Path "$configDir")) { - New-Item -ItemType Directory -Path "$configDir" -Force | Out-Null - } - - Write-Output "" - Write-Output "> Restoring existing config files..." - - Get-ChildItem -Path "$backupDir" -Recurse | Move-Item -Destination "$configDir" - Remove-Item "$backupDir" -Recurse -Force -} - # Make list of arguments to pass on to the script $arguments = $($PSBoundParameters.GetEnumerator() | ForEach-Object { if ($_.Value -eq $true) { @@ -220,13 +188,12 @@ if ($null -ne $debloatProcess) { $debloatProcess.WaitForExit() } -# Remove all remaining script files, except for configs, logs and backups +# Remove all remaining script files if (Test-Path $tempWorkPath) { Write-Output "" Write-Output "> Cleaning up..." - # Cleanup, remove Win11Debloat directory - Get-ChildItem -Path $tempWorkPath -Exclude Config,Logs,Backups | Remove-Item -Recurse -Force + Remove-Item $tempWorkPath -Recurse -Force } Write-Output "" diff --git a/Win11Debloat.ps1 b/Win11Debloat.ps1 index b6952f5..ff2f8b2 100644 --- a/Win11Debloat.ps1 +++ b/Win11Debloat.ps1 @@ -139,17 +139,17 @@ if (-not $isAdmin) { # Define script-level variables & paths $script:Version = "2026.06.14" $configPath = Join-Path $PSScriptRoot 'Config' -$logsPath = Join-Path $PSScriptRoot 'Logs' $schemasPath = Join-Path $PSScriptRoot 'Schemas' $scriptsPath = Join-Path $PSScriptRoot 'Scripts' +$script:AppDataPath = Join-Path $env:LOCALAPPDATA 'Win11Debloat' $script:AppsListFilePath = Join-Path $configPath 'Apps.json' $script:DefaultSettingsFilePath = Join-Path $configPath 'DefaultSettings.json' $script:FeaturesFilePath = Join-Path $configPath 'Features.json' -$script:SavedSettingsFilePath = Join-Path $configPath 'LastUsedSettings.json' -$script:DefaultLogPath = Join-Path $logsPath 'Win11Debloat.log' +$script:SavedSettingsFilePath = Join-Path $script:AppDataPath 'LastUsedSettings.json' +$script:DefaultLogPath = Join-Path (Join-Path $script:AppDataPath 'Logs') 'Win11Debloat.log' $script:RegfilesPath = Join-Path $PSScriptRoot 'Regfiles' -$script:RegistryBackupsPath = Join-Path $PSScriptRoot 'Backups' +$script:RegistryBackupsPath = Join-Path $script:AppDataPath 'Backups' $script:AssetsPath = Join-Path $PSScriptRoot 'Assets' $script:AppSelectionSchema = Join-Path $schemasPath 'AppSelectionWindow.xaml' $script:MainWindowSchema = Join-Path $schemasPath 'MainWindow.xaml'