diff --git a/Scripts/Features/Backup-RegistryState.ps1 b/Scripts/Features/Backup-RegistryState.ps1 index 30a8753..aad6639 100644 --- a/Scripts/Features/Backup-RegistryState.ps1 +++ b/Scripts/Features/Backup-RegistryState.ps1 @@ -4,7 +4,7 @@ .DESCRIPTION Resolves selected and undo features from the provided keys, captures their - registry state, and saves the result as a JSON file in the Backups/ folder. + registry state, and saves the result under %LOCALAPPDATA%\Win11Debloat\Backups. Returns the file path on success, $null if no registry-backed features exist. .PARAMETER ActionableKeys @@ -28,13 +28,8 @@ function New-RegistrySettingsBackup { } $timestamp = Get-Date - $backupDirectory = $script:RegistryBackupsPath - if (-not (Test-Path $backupDirectory)) { - New-Item -ItemType Directory -Path $backupDirectory -Force | Out-Null - } - $backupFileName = 'Win11Debloat-RegistryBackup-{0}.json' -f $timestamp.ToString('yyyyMMdd_HHmmss') - $backupFilePath = Join-Path $backupDirectory $backupFileName + $backupFilePath = Join-Path $script:RegistryBackupsPath $backupFileName $backupConfig = Get-RegistryBackupPayload -SelectedFeatures $selectedFeatures -UndoFeatures $undoFeatures -CreatedAt $timestamp if (-not (Save-ToFile -Config $backupConfig -FilePath $backupFilePath -MaxDepth 25)) { diff --git a/Scripts/FileIO/Save-ToFile.ps1 b/Scripts/FileIO/Save-ToFile.ps1 index f989a2b..80d0729 100644 --- a/Scripts/FileIO/Save-ToFile.ps1 +++ b/Scripts/FileIO/Save-ToFile.ps1 @@ -27,6 +27,8 @@ function Save-ToFile { ) try { + $directory = Split-Path -Parent $FilePath + if ($directory) { [void][System.IO.Directory]::CreateDirectory($directory) } $Config | ConvertTo-Json -Depth $MaxDepth | Set-Content -Path $FilePath -Encoding UTF8 -ErrorAction Stop return $true } diff --git a/Scripts/GUI/Show-MainWindow.ps1 b/Scripts/GUI/Show-MainWindow.ps1 index 5063957..9aa61fa 100644 --- a/Scripts/GUI/Show-MainWindow.ps1 +++ b/Scripts/GUI/Show-MainWindow.ps1 @@ -98,7 +98,7 @@ function Show-MainWindow { $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 -Parent $script:DefaultLogPath if (Test-Path $logsFolder) { Start-Process "explorer.exe" -ArgumentList $logsFolder } diff --git a/Tests/Registry-BackupCreation.Tests.ps1 b/Tests/Registry-BackupCreation.Tests.ps1 index 7158962..22d59aa 100644 --- a/Tests/Registry-BackupCreation.Tests.ps1 +++ b/Tests/Registry-BackupCreation.Tests.ps1 @@ -69,11 +69,11 @@ Describe 'New-RegistrySettingsBackup' { $script:RegistryBackupsPath = Join-Path $TestDrive 'Backups' $script:Features = @{ Feature = [PSCustomObject]@{ FeatureId = 'Feature'; RegistryKey = 'feature.reg' } } Mock Get-RegistryBackupPayload { @{ Version = '1.0' } } - Mock Save-ToFile { $true } Mock Write-Host {} } It 'returns null and does not write when no selected feature has registry data' { + Mock Save-ToFile { $true } $script:Features.Feature.RegistryKey = '' New-RegistrySettingsBackup -ActionableKeys @('Feature') | Should -BeNullOrEmpty @@ -85,7 +85,7 @@ Describe 'New-RegistrySettingsBackup' { $result | Should -Match 'Win11Debloat-RegistryBackup-\d{8}_\d{6}\.json$' Test-Path -LiteralPath $script:RegistryBackupsPath | Should -BeTrue - Should -Invoke Save-ToFile -Times 1 -Exactly -ParameterFilter { $FilePath -eq $result -and $MaxDepth -eq 25 } + (Get-Content -LiteralPath $result -Raw | ConvertFrom-Json).Version | Should -Be '1.0' } It 'throws when persistence reports failure' { diff --git a/Tests/Settings-And-Apps-FileIO.Tests.ps1 b/Tests/Settings-And-Apps-FileIO.Tests.ps1 index abcfd9a..d2f97d3 100644 --- a/Tests/Settings-And-Apps-FileIO.Tests.ps1 +++ b/Tests/Settings-And-Apps-FileIO.Tests.ps1 @@ -18,6 +18,14 @@ BeforeAll { } Describe 'Save-ToFile' { + It 'creates the destination directory on first use' { + $path = Join-Path $TestDrive 'UserData\LastUsedSettings.json' + + Save-ToFile -Config @{ Setting = $true } -FilePath $path | Should -BeTrue + + (Get-Content -LiteralPath $path -Raw | ConvertFrom-Json).Setting | Should -BeTrue + } + It 'reports the write error and returns false when persistence fails' { Mock Set-Content { throw [System.IO.IOException]::new('Disk is full') } Mock Write-Error {} diff --git a/Win11Debloat.ps1 b/Win11Debloat.ps1 index 2358546..6b980eb 100644 --- a/Win11Debloat.ps1 +++ b/Win11Debloat.ps1 @@ -174,20 +174,21 @@ if (-not $isAdmin) { # Define script-level variables & paths $script:Version = "2026.08.24" $configPath = Join-Path $PSScriptRoot 'Config' -$logsPath = Join-Path $PSScriptRoot 'Logs' +$script:UserDataPath = Join-Path $env:LOCALAPPDATA 'Win11Debloat' +$script:LogsPath = Join-Path $script:UserDataPath 'Logs' $schemasPath = Join-Path $PSScriptRoot 'Schemas' $scriptsPath = Join-Path $PSScriptRoot 'Scripts' $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:UiPreferencesFilePath = Join-Path $env:LOCALAPPDATA 'Win11Debloat\Preferences.json' +$script:SavedSettingsFilePath = Join-Path $script:UserDataPath 'LastUsedSettings.json' +$script:UiPreferencesFilePath = Join-Path $script:UserDataPath 'Preferences.json' $script:LanguagesPath = Join-Path $configPath 'Languages' $script:DefaultLanguagePath = Join-Path $script:LanguagesPath 'en-US' -$script:DefaultLogPath = Join-Path $logsPath 'Win11Debloat.log' +$script:DefaultLogPath = Join-Path $script:LogsPath 'Win11Debloat.log' $script:RegfilesPath = Join-Path $PSScriptRoot 'Regfiles' -$script:RegistryBackupsPath = Join-Path $PSScriptRoot 'Backups' +$script:RegistryBackupsPath = Join-Path $script:UserDataPath 'Backups' $script:AssetsPath = Join-Path $PSScriptRoot 'Assets' $script:AppSelectionSchema = Join-Path $schemasPath 'AppSelectionWindow.xaml' $script:MainWindowSchema = Join-Path $schemasPath 'MainWindow.xaml'