99
1010$ErrorActionPreference = ' Stop'
1111
12+ function Get-UserPathRegistryValue {
13+ $raw = [Environment ]::GetEnvironmentVariable(' Path' , ' User' )
14+ $kind = [Microsoft.Win32.RegistryValueKind ]::ExpandString
15+
16+ try {
17+ $key = [Microsoft.Win32.Registry ]::CurrentUser.OpenSubKey(' Environment' , $false )
18+ if ($null -ne $key ) {
19+ try {
20+ $stored = $key.GetValue (' Path' , $null , [Microsoft.Win32.RegistryValueOptions ]::DoNotExpandEnvironmentNames)
21+ if ($null -ne $stored ) {
22+ $raw = [string ]$stored
23+ }
24+ } catch {
25+ # Fallback to Environment API value
26+ }
27+
28+ try {
29+ $kind = $key.GetValueKind (' Path' )
30+ } catch {
31+ # Keep default ExpandString
32+ }
33+ $key.Close ()
34+ }
35+ } catch {
36+ # Fallback to Environment API value
37+ }
38+
39+ return @ {
40+ Raw = $raw
41+ Kind = $kind
42+ }
43+ }
44+
1245function Normalize-PathEntry {
1346 param ([string ]$Value )
1447
@@ -19,7 +52,8 @@ function Normalize-PathEntry {
1952 return $Value.Trim ().Trim(' "' ).TrimEnd(' \' ).ToLowerInvariant()
2053}
2154
22- $current = [Environment ]::GetEnvironmentVariable(' Path' , ' User' )
55+ $pathMeta = Get-UserPathRegistryValue
56+ $current = $pathMeta.Raw
2357$entries = @ ()
2458if (-not [string ]::IsNullOrWhiteSpace($current )) {
2559 $entries = $current -split ' ;' | Where-Object { -not [string ]::IsNullOrWhiteSpace($_ ) }
@@ -54,35 +88,63 @@ if ($Action -eq 'add') {
5488 $status = ' updated'
5589}
5690
91+ $isLikelyCorruptedWrite = (
92+ $Action -eq ' add' -and
93+ $entries.Count -gt 1 -and
94+ $nextEntries.Count -le 1
95+ )
96+ if ($isLikelyCorruptedWrite ) {
97+ throw " Refusing to rewrite user PATH: input had $ ( $entries.Count ) entries but output has $ ( $nextEntries.Count ) ."
98+ }
99+
57100$newPath = if ($nextEntries.Count -eq 0 ) { $null } else { $nextEntries -join ' ;' }
58- [Environment ]::SetEnvironmentVariable(' Path' , $newPath , ' User' )
59-
60- Add-Type - Namespace OpenClaw - Name NativeMethods - MemberDefinition @"
61- using System;
62- using System.Runtime.InteropServices;
63- public static class NativeMethods {
64- [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
65- public static extern IntPtr SendMessageTimeout(
66- IntPtr hWnd,
67- int Msg,
68- IntPtr wParam,
69- string lParam,
70- int fuFlags,
71- int uTimeout,
72- out IntPtr lpdwResult
73- );
101+ try {
102+ $key = [Microsoft.Win32.Registry ]::CurrentUser.OpenSubKey(' Environment' , $true )
103+ if ($null -eq $key ) {
104+ throw ' Unable to open HKCU\Environment for write.'
105+ }
106+
107+ if ([string ]::IsNullOrWhiteSpace($newPath )) {
108+ $key.DeleteValue (' Path' , $false )
109+ } else {
110+ $kind = if ($pathMeta.Kind -eq [Microsoft.Win32.RegistryValueKind ]::String) {
111+ [Microsoft.Win32.RegistryValueKind ]::String
112+ } else {
113+ [Microsoft.Win32.RegistryValueKind ]::ExpandString
114+ }
115+ $key.SetValue (' Path' , $newPath , $kind )
116+ }
117+ $key.Close ()
118+ } catch {
119+ throw " Failed to write HKCU\\Environment\\Path: $ ( $_.Exception.Message ) "
74120}
121+
122+ try {
123+ Add-Type - Namespace OpenClaw - Name NativeMethods - MemberDefinition @"
124+ [System.Runtime.InteropServices.DllImport("user32.dll", SetLastError = true, CharSet = System.Runtime.InteropServices.CharSet.Auto)]
125+ public static extern System.IntPtr SendMessageTimeout(
126+ System.IntPtr hWnd,
127+ int Msg,
128+ System.IntPtr wParam,
129+ string lParam,
130+ int fuFlags,
131+ int uTimeout,
132+ out System.IntPtr lpdwResult
133+ );
75134"@
76135
77- $result = [IntPtr ]::Zero
78- [OpenClaw.NativeMethods ]::SendMessageTimeout(
79- [IntPtr ]0xffff ,
80- 0x001A ,
81- [IntPtr ]::Zero,
82- ' Environment' ,
83- 0x0002 ,
84- 5000 ,
85- [ref ]$result
86- ) | Out-Null
136+ $result = [IntPtr ]::Zero
137+ [OpenClaw.NativeMethods ]::SendMessageTimeout(
138+ [IntPtr ]0xffff ,
139+ 0x001A ,
140+ [IntPtr ]::Zero,
141+ ' Environment' ,
142+ 0x0002 ,
143+ 5000 ,
144+ [ref ]$result
145+ ) | Out-Null
146+ } catch {
147+ Write-Warning " PATH updated but failed to broadcast environment change: $ ( $_.Exception.Message ) "
148+ }
87149
88150Write-Output $status
0 commit comments