From c3e368bddcf3452a44284480d2effb6eb6e6ee33 Mon Sep 17 00:00:00 2001 From: Irfan Hardiyanto Date: Fri, 19 Jun 2026 01:45:47 +0700 Subject: [PATCH] feat: v1.8.2 - broadcast WM_SETTINGCHANGE on PATH change (B1) After changing the User PATH, broadcast WM_SETTINGCHANGE (Environment) so Explorer and the terminals it spawns pick up the new PATH without a logout. - phpvm.ps1: Send-EnvChangeBroadcast (P/Invoke SendMessageTimeout, HWND_BROADCAST) called from Invoke-Use after persisting PATH. Dropped the "restart your terminal" warning - the current session is already updated in-process and new terminals get the change via the broadcast. Also indented the `use` php --version output that 1.8.0's replace_all had missed. - install.ps1 / uninstall.ps1: broadcast after their User PATH writes too. Version bump to 1.8.2 across the 5 sources. PSScriptAnalyzer clean, 47/47 Pester. --- linux/install.sh | 2 +- linux/phpvm.sh | 2 +- version.txt | 2 +- windows/install.ps1 | 23 ++++++++++++++++++++++- windows/phpvm.ps1 | 34 +++++++++++++++++++++++++++++++--- windows/uninstall.ps1 | 22 ++++++++++++++++++++++ 6 files changed, 78 insertions(+), 7 deletions(-) diff --git a/linux/install.sh b/linux/install.sh index 6cee393..68efcfc 100644 --- a/linux/install.sh +++ b/linux/install.sh @@ -6,7 +6,7 @@ set -e -PHPVM_VERSION="1.8.1" +PHPVM_VERSION="1.8.2" PHPVM_DIR="${PHPVM_DIR:-$HOME/.phpvm}" PHPVM_REPO="https://raw.githubusercontent.com/devhardiyanto/phpvm/main" diff --git a/linux/phpvm.sh b/linux/phpvm.sh index 5802726..63bec29 100644 --- a/linux/phpvm.sh +++ b/linux/phpvm.sh @@ -10,7 +10,7 @@ # phpvm use 8.3.0 # ============================================================================== -PHPVM_VERSION="1.8.1" +PHPVM_VERSION="1.8.2" PHPVM_DIR="${PHPVM_DIR:-$HOME/.phpvm}" PHPVM_VERSIONS="$PHPVM_DIR/versions" PHPVM_CURRENT="$PHPVM_DIR/current" diff --git a/version.txt b/version.txt index a8fdfda..53adb84 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -1.8.1 +1.8.2 diff --git a/windows/install.ps1 b/windows/install.ps1 index 3973957..29c5670 100644 --- a/windows/install.ps1 +++ b/windows/install.ps1 @@ -7,7 +7,7 @@ Set-StrictMode -Version Latest $ErrorActionPreference = "Stop" -$PHPVM_VERSION = "1.8.1" +$PHPVM_VERSION = "1.8.2" $PHPVM_DIR = if ($env:PHPVM_DIR) { $env:PHPVM_DIR } else { "$env:USERPROFILE\.phpvm" } $PHPVM_BIN = "$PHPVM_DIR\bin" @@ -15,6 +15,26 @@ function Write-Ok ($m) { Write-Host " $m" -ForegroundColor Green } function Write-Step ($m) { Write-Host " > $m" -ForegroundColor Cyan } function Write-Warn ($m) { Write-Host " [warn] $m" -ForegroundColor Yellow } +# Broadcast WM_SETTINGCHANGE so new terminals pick up the PATH without a logout. +function Send-EnvChangeBroadcast { + if (-not ("PHPVM.NativeMethods" -as [type])) { + try { + Add-Type -Namespace PHPVM -Name NativeMethods -MemberDefinition @' +[System.Runtime.InteropServices.DllImport("user32.dll", SetLastError = true, CharSet = System.Runtime.InteropServices.CharSet.Auto)] +public static extern System.IntPtr SendMessageTimeout( + System.IntPtr hWnd, uint Msg, System.IntPtr wParam, string lParam, + uint fuFlags, uint uTimeout, out System.UIntPtr lpdwResult); +'@ + } catch { return } + } + $out = [System.UIntPtr]::Zero + try { + [void][PHPVM.NativeMethods]::SendMessageTimeout( + [System.IntPtr]0xffff, 0x1A, [System.IntPtr]::Zero, + "Environment", 0x2, 5000, [ref]$out) + } catch { $null = $_ } +} + Write-Host "" Write-Host " phpvm $PHPVM_VERSION - PHP Version Manager for Windows" -ForegroundColor Cyan Write-Host " ------------------------------------------------------" -ForegroundColor DarkGray @@ -60,6 +80,7 @@ if ($null -eq $userPath) { $userPath = "" } if ($userPath -notlike "*$PHPVM_BIN*") { $newPath = "$PHPVM_BIN;$userPath" -replace ";{2,}", ";" [Environment]::SetEnvironmentVariable("PATH", $newPath, "User") + Send-EnvChangeBroadcast Write-Ok "Added to user PATH -> $PHPVM_BIN" } else { Write-Warn "$PHPVM_BIN already in PATH, skipping." diff --git a/windows/phpvm.ps1 b/windows/phpvm.ps1 index 3f4145b..9bb2675 100644 --- a/windows/phpvm.ps1 +++ b/windows/phpvm.ps1 @@ -15,7 +15,7 @@ Set-StrictMode -Version Latest $ErrorActionPreference = "Stop" # -- Constants ----------------------------------------------------------------- -$PHPVM_VERSION = "1.8.1" +$PHPVM_VERSION = "1.8.2" $PHPVM_DIR = if ($env:PHPVM_DIR) { $env:PHPVM_DIR } else { "$env:USERPROFILE\.phpvm" } $VERSIONS_DIR = "$PHPVM_DIR\versions" $CURRENT_LINK = "$PHPVM_DIR\current" @@ -65,6 +65,31 @@ function Write-Step ($m) { Write-Host " > $m" -ForegroundColor Cyan } function Write-Warn ($m) { Write-Host " [warn] $m" -ForegroundColor Yellow } function Write-Dim ($m) { Write-Host " $m" -ForegroundColor DarkGray } +# Broadcast WM_SETTINGCHANGE so running processes (Explorer, and the terminals +# it spawns afterward) refresh their environment block after a User PATH change, +# instead of needing a logout. Best-effort; any failure is swallowed. +function Send-EnvChangeBroadcast { + if (-not ("PHPVM.NativeMethods" -as [type])) { + try { + Add-Type -Namespace PHPVM -Name NativeMethods -MemberDefinition @' +[System.Runtime.InteropServices.DllImport("user32.dll", SetLastError = true, CharSet = System.Runtime.InteropServices.CharSet.Auto)] +public static extern System.IntPtr SendMessageTimeout( + System.IntPtr hWnd, uint Msg, System.IntPtr wParam, string lParam, + uint fuFlags, uint uTimeout, out System.UIntPtr lpdwResult); +'@ + } catch { return } + } + $HWND_BROADCAST = [System.IntPtr]0xffff + $WM_SETTINGCHANGE = 0x1A + $SMTO_ABORTIFHUNG = 0x2 + $out = [System.UIntPtr]::Zero + try { + [void][PHPVM.NativeMethods]::SendMessageTimeout( + $HWND_BROADCAST, $WM_SETTINGCHANGE, [System.IntPtr]::Zero, + "Environment", $SMTO_ABORTIFHUNG, 5000, [ref]$out) + } catch { $null = $_ } +} + # -- Init ---------------------------------------------------------------------- function Initialize-PHPVM { # GitHub blocks TLS < 1.2 @@ -402,14 +427,17 @@ function Invoke-Use ([string]$ver) { $newPath = (@($CURRENT_LINK) + $parts -join ";") -replace ";{2,}", ";" [Environment]::SetEnvironmentVariable("PATH", $newPath, "User") if ($env:PATH -notlike "*$CURRENT_LINK*") { $env:PATH = "$CURRENT_LINK;$env:PATH" } + # Propagate the PATH change to the rest of the system so new terminals get it + # without a logout. This session was already updated on the line above. + Send-EnvChangeBroadcast Write-Ok "Now using PHP $ver" try { - & "$CURRENT_LINK\php.exe" --version 2>$null + & "$CURRENT_LINK\php.exe" --version 2>$null | ForEach-Object { Write-Host " $_" } } catch { return } - Write-Warn "Restart your terminal if 'php -v' still shows the previous version." + Write-Dim "Active in this terminal now. Other already-open terminals pick it up when reopened." } function Invoke-List { diff --git a/windows/uninstall.ps1 b/windows/uninstall.ps1 index 8c83c5a..56cca34 100644 --- a/windows/uninstall.ps1 +++ b/windows/uninstall.ps1 @@ -31,6 +31,27 @@ function Write-Warn ($m) { Write-Host " [warn] $m" -ForegroundColor Yellow } function Write-Err ($m) { Write-Host " [error] $m" -ForegroundColor Red } function Write-Dim ($m) { Write-Host " $m" -ForegroundColor DarkGray } +# Broadcast WM_SETTINGCHANGE so running processes drop the removed PATH entry +# without a logout. Best-effort. +function Send-EnvChangeBroadcast { + if (-not ("PHPVM.NativeMethods" -as [type])) { + try { + Add-Type -Namespace PHPVM -Name NativeMethods -MemberDefinition @' +[System.Runtime.InteropServices.DllImport("user32.dll", SetLastError = true, CharSet = System.Runtime.InteropServices.CharSet.Auto)] +public static extern System.IntPtr SendMessageTimeout( + System.IntPtr hWnd, uint Msg, System.IntPtr wParam, string lParam, + uint fuFlags, uint uTimeout, out System.UIntPtr lpdwResult); +'@ + } catch { return } + } + $out = [System.UIntPtr]::Zero + try { + [void][PHPVM.NativeMethods]::SendMessageTimeout( + [System.IntPtr]0xffff, 0x1A, [System.IntPtr]::Zero, + "Environment", 0x2, 5000, [ref]$out) + } catch { $null = $_ } +} + if ($Help) { Write-Host "" Write-Host " phpvm uninstaller" @@ -79,6 +100,7 @@ $parts = $userPath -split ";" | Where-Object { $newPath = ($parts -join ";") -replace ";{2,}", ";" if ($newPath -ne $userPath) { [Environment]::SetEnvironmentVariable("PATH", $newPath, "User") + Send-EnvChangeBroadcast Write-Ok "Removed phpvm from User PATH." } else { Write-Dim "No phpvm entry found in User PATH."