Public/Add-MSIXPSFEnvVarFixup.ps1
|
function Add-MSIXPSFEnvVarFixup { <# .SYNOPSIS Adds an EnvVarFixup entry to an MSIX package PSF configuration. .DESCRIPTION Writes an EnvVarFixup entry into config.json.xml for the specified process. EnvVarFixup injects or overrides environment variables at process startup, before the application reads them. Call this function once per variable. Multiple calls accumulate variables under the same process entry. If the variable name already exists for the process, its value is replaced. The PSF launcher selects the correct architecture-specific DLL at runtime; config.json always references EnvVarFixup.dll without an architecture suffix. .PARAMETER MSIXFolder Path to the expanded MSIX package folder (must contain config.json.xml). .PARAMETER Executable Regex pattern matching the process entry to configure. Default: ".*" (all processes). .PARAMETER Name Name of the environment variable to set or override. .PARAMETER Value Value for the environment variable. Supports standard Windows environment variable expansion (e.g. "%APPDATA%\MyApp"). .EXAMPLE Add-MSIXPSFEnvVarFixup -MSIXFolder "C:\MSIXTemp\MyApp" -Name "MY_VAR" -Value "C:\Data" .EXAMPLE Add-MSIXPSFEnvVarFixup -MSIXFolder "C:\MSIXTemp\MyApp" -Executable "myapp$" ` -Name "APPDATA_PATH" -Value "%MsixWritablePackageRoot%\VFS\LocalAppData\MyApp" .EXAMPLE # Set multiple variables $pkg = Open-MSIXPackage -MsixFile "C:\Packages\MyApp.msix" -Force Add-MSIXPSFEnvVarFixup -MSIXFolder $pkg -Name "HOME" -Value "%MsixWritablePackageRoot%" Add-MSIXPSFEnvVarFixup -MSIXFolder $pkg -Name "TMPDIR" -Value "%TEMP%" .NOTES EnvVarFixup source: https://github.com/microsoft/MSIX-PackageSupportFramework https://www.nick-it.de Andreas Nick, 2026 #> [CmdletBinding()] param( [Parameter(Mandatory = $true, ValueFromPipeline = $true, Position = 0)] [System.IO.DirectoryInfo] $MSIXFolder, [String] $Executable = '.*', [Parameter(Mandatory = $true)] [String] $Name, [Parameter(Mandatory = $true)] [String] $Value ) process { if (-not (Test-Path $MSIXFolder.FullName -PathType Container)) { Write-Error "MSIXFolder not found: $($MSIXFolder.FullName)" return } try { $null = [System.Text.RegularExpressions.Regex]::new($Executable) } catch { Write-Error "-Executable '$Executable' is not a valid regular expression: $_" return } $configXmlPath = Join-Path $MSIXFolder 'config.json.xml' if (-not (Test-Path $configXmlPath)) { Write-Warning "config.json.xml not found in: $($MSIXFolder.FullName). Run Add-MSXIXPSFShim first." return } $conxml = New-Object xml $conxml.Load($configXmlPath) Initialize-MSIXPSFProcessSection -ConXml $conxml # Locate or create the target process node $execNode = $conxml.SelectSingleNode("//processes/process/executable[text()='$Executable']") if (-not $execNode) { $proc = $conxml.CreateElement('process') $exec = $conxml.CreateElement('executable') $exec.InnerText = $Executable $proc.AppendChild($exec) | Out-Null $conxml.SelectSingleNode('//processes').AppendChild($proc) | Out-Null $execNode = $conxml.SelectSingleNode("//processes/process/executable[text()='$Executable']") } $processNode = $execNode.ParentNode if ($null -eq $processNode.SelectSingleNode('fixups')) { $processNode.AppendChild($conxml.CreateElement('fixups')) | Out-Null } # Find or create the EnvVarFixup entry for this process $fixupNode = $processNode.SelectSingleNode("fixups/fixup/dll[text()='EnvVarFixup.dll']") if ($null -eq $fixupNode) { $fixup = $conxml.CreateElement('fixup') $dllEl = $conxml.CreateElement('dll') $dllEl.InnerText = 'EnvVarFixup.dll' $fixup.AppendChild($dllEl) | Out-Null $cfgEl = $conxml.CreateElement('config') $varsEl = $conxml.CreateElement('envVariables') $cfgEl.AppendChild($varsEl) | Out-Null $fixup.AppendChild($cfgEl) | Out-Null $processNode.SelectSingleNode('fixups').AppendChild($fixup) | Out-Null $fixupNode = $processNode.SelectSingleNode("fixups/fixup/dll[text()='EnvVarFixup.dll']") } $fixupEl = $fixupNode.ParentNode $varsNode = $fixupEl.SelectSingleNode('config/envVariables') # Replace existing entry with same name (idempotency) $existing = $varsNode.SelectSingleNode("envVariable[name='$Name']") if ($null -ne $existing) { $existing.SelectSingleNode('value').InnerText = $Value Write-Verbose "Updated EnvVarFixup: $Name = $Value (executable: $Executable)" } else { $varEl = $conxml.CreateElement('envVariable') $nameEl = $conxml.CreateElement('name') $valueEl = $conxml.CreateElement('value') $nameEl.InnerText = $Name $valueEl.InnerText = $Value $varEl.AppendChild($nameEl) | Out-Null $varEl.AppendChild($valueEl) | Out-Null $varsNode.AppendChild($varEl) | Out-Null Write-Verbose "Added EnvVarFixup: $Name = $Value (executable: $Executable)" } $conxml.PreserveWhiteSpace = $false $conxml.Save($configXmlPath) } } |