Preserve configuration paths in copied export commands (#5172)

Co-authored-by: Chris Titus <contact@christitus.com>
This commit is contained in:
Kerim SabicandChris Titus authored and GitHub committed 2026-10-21 13:39:45 -05:00
1 parent 6100cf171a
commit da0aa2f8b8
3 files changed
+50 -2

No files matched your search

+3 -1
View File
@@ -33,7 +33,9 @@ To create your own config file:
Local configuration paths are used exactly as provided when importing or exporting. Square brackets in folder or file names, such as `C:\Configs\setup[1].json`, are treated as part of the name rather than wildcard patterns.
Once you have exported a config, launch WinUtil with it using this command:
Export also copies a command to the clipboard that launches WinUtil with the saved configuration. The copied command preserves special characters in the path, including apostrophes, dollar signs, and backticks.
You can also launch WinUtil with an exported config using this command:
```powershell
& ([ScriptBlock]::Create((irm "https://christitus.com/win"))) -Config "C:\Path\To\Config.json"
```
+3 -1
View File
@@ -60,7 +60,9 @@ function Invoke-WPFImpex {
}
$jsonFile = $allConfs | ConvertTo-Json
$jsonFile | Out-File -LiteralPath $Config -Force
"iex ""& { `$(irm https://christitus.com/win) } -Config '$Config'""" | Set-Clipboard
# Keep the path literal when the copied command is pasted into PowerShell.
$escapedConfig = [System.Management.Automation.Language.CodeGeneration]::EscapeSingleQuotedStringContent($Config)
"& ([ScriptBlock]::Create((Invoke-RestMethod 'https://christitus.com/win'))) -Config '$escapedConfig'" | Set-Clipboard
}
} catch {
Write-Error "An error occurred while exporting: $_"
+44
View File
@@ -0,0 +1,44 @@
BeforeAll {
$repoRoot = (Resolve-Path (Join-Path $PSScriptRoot "..")).Path
. (Join-Path $repoRoot "functions\public\Invoke-WPFImpex.ps1")
}
Describe "Exported configuration clipboard command" {
BeforeEach {
$script:sync = [Hashtable]::Synchronized(@{
selectedApps = @("WPFInstallGit")
selectedTweaks = @()
selectedToggles = @()
selectedFeatures = @()
selectedAppx = @()
})
$script:copiedCommand = $null
Mock Set-Clipboard { $script:copiedCommand = $Value }
# Execute only a harmless replacement that echoes the received path.
Mock Invoke-RestMethod { 'param([string]$Config) $Config' }
}
AfterEach {
Remove-Variable -Name sync, copiedCommand -Scope Script -ErrorAction SilentlyContinue
}
It "preserves the configuration path for <FileName> when the copied command runs" -ForEach @(
@{ FileName = 'my settings.json' }
@{ FileName = "O'Brien.json" }
@{ FileName = ('O{0}Brien.json' -f [char]0x2019) }
@{ FileName = '$HOME.json' }
@{ FileName = 'back`tick.json' }
@{ FileName = '$(1+2).json' }
) {
$configPath = Join-Path $TestDrive $FileName
Invoke-WPFImpex -type "export" -Config $configPath
$script:copiedCommand | Should -Not -BeNullOrEmpty
$result = & ([scriptblock]::Create($script:copiedCommand))
$result | Should -Be $configPath
Should -Invoke Invoke-RestMethod -Times 1 -Exactly -ParameterFilter {
$Uri -eq 'https://christitus.com/win'
}
}
}