@@ -134,7 +134,11 @@ pub fn wait_for_parent() -> Result<()> {
134
134
135
135
pub fn do_add_to_path ( methods : & [ PathUpdateMethod ] ) -> Result < ( ) > {
136
136
assert ! ( methods. len( ) == 1 && methods[ 0 ] == PathUpdateMethod :: Windows ) ;
137
+ let new_path = _with_path_cargo_home_bin ( _add_to_path) ?;
138
+ _apply_new_path ( new_path)
139
+ }
137
140
141
+ fn _apply_new_path ( new_path : Option < String > ) -> Result < ( ) > {
138
142
use std:: ptr;
139
143
use winapi:: shared:: minwindef:: * ;
140
144
use winapi:: um:: winuser:: {
@@ -143,7 +147,7 @@ pub fn do_add_to_path(methods: &[PathUpdateMethod]) -> Result<()> {
143
147
use winreg:: enums:: { RegType , HKEY_CURRENT_USER , KEY_READ , KEY_WRITE } ;
144
148
use winreg:: { RegKey , RegValue } ;
145
149
146
- let new_path = match _with_path_cargo_home_bin ( _add_to_path ) ? {
150
+ let new_path = match new_path {
147
151
Some ( new_path) => new_path,
148
152
None => return Ok ( ( ) ) , // No need to set the path
149
153
} ;
@@ -153,14 +157,19 @@ pub fn do_add_to_path(methods: &[PathUpdateMethod]) -> Result<()> {
153
157
. open_subkey_with_flags ( "Environment" , KEY_READ | KEY_WRITE )
154
158
. chain_err ( || ErrorKind :: PermissionDenied ) ?;
155
159
156
- let reg_value = RegValue {
157
- bytes : utils:: string_to_winreg_bytes ( & new_path) ,
158
- vtype : RegType :: REG_EXPAND_SZ ,
159
- } ;
160
-
161
- environment
162
- . set_raw_value ( "PATH" , & reg_value)
163
- . chain_err ( || ErrorKind :: PermissionDenied ) ?;
160
+ if new_path. is_empty ( ) {
161
+ environment
162
+ . delete_value ( "PATH" )
163
+ . chain_err ( || ErrorKind :: PermissionDenied ) ?;
164
+ } else {
165
+ let reg_value = RegValue {
166
+ bytes : utils:: string_to_winreg_bytes ( & new_path) ,
167
+ vtype : RegType :: REG_EXPAND_SZ ,
168
+ } ;
169
+ environment
170
+ . set_raw_value ( "PATH" , & reg_value)
171
+ . chain_err ( || ErrorKind :: PermissionDenied ) ?;
172
+ }
164
173
165
174
// Tell other processes to update their environment
166
175
unsafe {
@@ -258,53 +267,8 @@ where
258
267
259
268
pub fn do_remove_from_path ( methods : & [ PathUpdateMethod ] ) -> Result < ( ) > {
260
269
assert ! ( methods. len( ) == 1 && methods[ 0 ] == PathUpdateMethod :: Windows ) ;
261
-
262
- use std:: ptr;
263
- use winapi:: shared:: minwindef:: * ;
264
- use winapi:: um:: winuser:: {
265
- SendMessageTimeoutA , HWND_BROADCAST , SMTO_ABORTIFHUNG , WM_SETTINGCHANGE ,
266
- } ;
267
- use winreg:: enums:: { RegType , HKEY_CURRENT_USER , KEY_READ , KEY_WRITE } ;
268
- use winreg:: { RegKey , RegValue } ;
269
-
270
- let new_path = match _with_path_cargo_home_bin ( _remove_from_path) ? {
271
- Some ( new_path) => new_path,
272
- None => return Ok ( ( ) ) , // No need to set the path
273
- } ;
274
-
275
- let root = RegKey :: predef ( HKEY_CURRENT_USER ) ;
276
- let environment = root
277
- . open_subkey_with_flags ( "Environment" , KEY_READ | KEY_WRITE )
278
- . chain_err ( || ErrorKind :: PermissionDenied ) ?;
279
-
280
- if new_path. is_empty ( ) {
281
- environment
282
- . delete_value ( "PATH" )
283
- . chain_err ( || ErrorKind :: PermissionDenied ) ?;
284
- } else {
285
- let reg_value = RegValue {
286
- bytes : utils:: string_to_winreg_bytes ( & new_path) ,
287
- vtype : RegType :: REG_EXPAND_SZ ,
288
- } ;
289
- environment
290
- . set_raw_value ( "PATH" , & reg_value)
291
- . chain_err ( || ErrorKind :: PermissionDenied ) ?;
292
- }
293
-
294
- // Tell other processes to update their environment
295
- unsafe {
296
- SendMessageTimeoutA (
297
- HWND_BROADCAST ,
298
- WM_SETTINGCHANGE ,
299
- 0 as WPARAM ,
300
- "Environment\0 " . as_ptr ( ) as LPARAM ,
301
- SMTO_ABORTIFHUNG ,
302
- 5000 ,
303
- ptr:: null_mut ( ) ,
304
- ) ;
305
- }
306
-
307
- Ok ( ( ) )
270
+ let new_path = _with_path_cargo_home_bin ( _remove_from_path) ?;
271
+ _apply_new_path ( new_path)
308
272
}
309
273
310
274
pub fn run_update ( setup_path : & Path ) -> Result < utils:: ExitCode > {
@@ -548,6 +512,31 @@ mod tests {
548
512
) ;
549
513
}
550
514
515
+ #[ test]
516
+ fn windows_path_regkey_type ( ) {
517
+ // per issue #261, setting PATH should use REG_EXPAND_SZ.
518
+ let tp = Box :: new ( currentprocess:: TestProcess :: default ( ) ) ;
519
+ with_registry_edits ( & || {
520
+ currentprocess:: with ( tp. clone ( ) , || {
521
+ let root = RegKey :: predef ( HKEY_CURRENT_USER ) ;
522
+ let environment = root
523
+ . open_subkey_with_flags ( "Environment" , KEY_READ | KEY_WRITE )
524
+ . unwrap ( ) ;
525
+ environment. delete_value ( "PATH" ) . unwrap ( ) ;
526
+
527
+ assert_eq ! ( ( ) , super :: _apply_new_path( Some ( "foo" . into( ) ) ) . unwrap( ) ) ;
528
+
529
+ let root = RegKey :: predef ( HKEY_CURRENT_USER ) ;
530
+ let environment = root
531
+ . open_subkey_with_flags ( "Environment" , KEY_READ | KEY_WRITE )
532
+ . unwrap ( ) ;
533
+ let path = environment. get_raw_value ( "PATH" ) . unwrap ( ) ;
534
+ assert_eq ! ( path. vtype, RegType :: REG_EXPAND_SZ ) ;
535
+ assert_eq ! ( utils:: string_to_winreg_bytes( "foo" ) , & path. bytes[ ..] ) ;
536
+ } )
537
+ } ) ;
538
+ }
539
+
551
540
#[ test]
552
541
fn windows_uninstall_removes_semicolon_from_path_prefix ( ) {
553
542
assert_eq ! (
0 commit comments