Modify HKEY_CURRENT_USER\Environment\PATH on Windows (#4614)
Thanks for the Windows registry editing code rustup.rs!
This commit is contained in:
parent
91b23f8316
commit
ec0007217d
|
@ -26,7 +26,7 @@ name = "ansi_term"
|
|||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -92,7 +92,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
dependencies = [
|
||||
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -110,7 +110,7 @@ dependencies = [
|
|||
"cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-demangle 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -376,7 +376,7 @@ dependencies = [
|
|||
"atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -418,7 +418,7 @@ dependencies = [
|
|||
"regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"termios 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -616,7 +616,7 @@ dependencies = [
|
|||
"cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"redox_users 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -767,7 +767,7 @@ dependencies = [
|
|||
"cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1250,7 +1250,7 @@ version = "0.5.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cc 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1310,7 +1310,7 @@ version = "0.6.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1319,7 +1319,7 @@ version = "0.7.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1447,7 +1447,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
dependencies = [
|
||||
"cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1587,7 +1587,7 @@ dependencies = [
|
|||
"rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1739,7 +1739,7 @@ dependencies = [
|
|||
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1757,7 +1757,7 @@ dependencies = [
|
|||
"rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1805,7 +1805,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
dependencies = [
|
||||
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1818,7 +1818,7 @@ dependencies = [
|
|||
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1927,7 +1927,7 @@ name = "remove_dir_all"
|
|||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2019,7 +2019,7 @@ version = "0.1.15"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2172,7 +2172,7 @@ dependencies = [
|
|||
"cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2521,6 +2521,8 @@ dependencies = [
|
|||
"tar 0.4.26 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winreg 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2950,7 +2952,7 @@ dependencies = [
|
|||
"rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -3002,7 +3004,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
dependencies = [
|
||||
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -3330,7 +3332,7 @@ version = "2.2.7"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"same-file 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
|
@ -3360,7 +3362,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.6"
|
||||
version = "0.3.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -3382,7 +3384,7 @@ name = "winapi-util"
|
|||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -3395,10 +3397,18 @@ name = "wincolor"
|
|||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winreg"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ws"
|
||||
version = "0.8.1"
|
||||
|
@ -3746,12 +3756,13 @@ dependencies = [
|
|||
"checksum want 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "797464475f30ddb8830cc529aaaae648d581f99e2036a928877dfde027ddf6b3"
|
||||
"checksum which 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b57acb10231b9493c8472b20cb57317d0679a49e0bdbee44b3b803a6473af164"
|
||||
"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
|
||||
"checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0"
|
||||
"checksum winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "f10e386af2b13e47c89e7236a7a14a086791a2b88ebad6df9bf42040195cf770"
|
||||
"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
|
||||
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
"checksum winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7168bab6e1daee33b4557efd0e95d5ca70a03706d39fa5f3fe7a236f584b03c9"
|
||||
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
"checksum wincolor 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "561ed901ae465d6185fa7864d63fbd5720d0ef718366c9a4dc83cf6170d7e9ba"
|
||||
"checksum winreg 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "daf67b95d0b1bf421c4f11048d63110ca3719977169eec86396b614c8942b6e0"
|
||||
"checksum ws 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ec91ea61b83ce033c43c06c52ddc7532f465c0153281610d44c58b74083aee1a"
|
||||
"checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e"
|
||||
"checksum xattr 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "244c3741f4240ef46274860397c7c74e50eb23624996930e484c16679633a54c"
|
||||
|
|
|
@ -36,6 +36,10 @@ tar = "0.4.26"
|
|||
tempdir = "0.3.7"
|
||||
url = "1.7.2"
|
||||
|
||||
[target."cfg(windows)".dependencies]
|
||||
winapi = "0.3.7"
|
||||
winreg = "0.6"
|
||||
|
||||
[[bin]]
|
||||
name = "solana-install"
|
||||
path = "src/main-install.rs"
|
||||
|
|
|
@ -276,6 +276,217 @@ fn check_env_path_for_bin_dir(config: &Config) {
|
|||
}
|
||||
}
|
||||
|
||||
/// Encodes a UTF-8 string as a null-terminated UCS-2 string in bytes
|
||||
#[cfg(windows)]
|
||||
pub fn string_to_winreg_bytes(s: &str) -> Vec<u8> {
|
||||
use std::ffi::OsString;
|
||||
use std::os::windows::ffi::OsStrExt;
|
||||
let v: Vec<_> = OsString::from(format!("{}\x00", s)).encode_wide().collect();
|
||||
unsafe { std::slice::from_raw_parts(v.as_ptr() as *const u8, v.len() * 2).to_vec() }
|
||||
}
|
||||
|
||||
// This is used to decode the value of HKCU\Environment\PATH. If that
|
||||
// key is not Unicode (or not REG_SZ | REG_EXPAND_SZ) then this
|
||||
// returns null. The winreg library itself does a lossy unicode
|
||||
// conversion.
|
||||
#[cfg(windows)]
|
||||
pub fn string_from_winreg_value(val: &winreg::RegValue) -> Option<String> {
|
||||
use std::slice;
|
||||
use winreg::enums::RegType;
|
||||
|
||||
match val.vtype {
|
||||
RegType::REG_SZ | RegType::REG_EXPAND_SZ => {
|
||||
// Copied from winreg
|
||||
let words = unsafe {
|
||||
slice::from_raw_parts(val.bytes.as_ptr() as *const u16, val.bytes.len() / 2)
|
||||
};
|
||||
let mut s = if let Ok(s) = String::from_utf16(words) {
|
||||
s
|
||||
} else {
|
||||
return None;
|
||||
};
|
||||
while s.ends_with('\u{0}') {
|
||||
s.pop();
|
||||
}
|
||||
Some(s)
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
// Get the windows PATH variable out of the registry as a String. If
|
||||
// this returns None then the PATH variable is not Unicode and we
|
||||
// should not mess with it.
|
||||
#[cfg(windows)]
|
||||
fn get_windows_path_var() -> Result<Option<String>, String> {
|
||||
use winreg::enums::{HKEY_CURRENT_USER, KEY_READ, KEY_WRITE};
|
||||
use winreg::RegKey;
|
||||
|
||||
let root = RegKey::predef(HKEY_CURRENT_USER);
|
||||
let environment = root
|
||||
.open_subkey_with_flags("Environment", KEY_READ | KEY_WRITE)
|
||||
.map_err(|err| format!("Unable to open HKEY_CURRENT_USER\\Environment: {}", err))?;
|
||||
|
||||
let reg_value = environment.get_raw_value("PATH");
|
||||
match reg_value {
|
||||
Ok(val) => {
|
||||
if let Some(s) = string_from_winreg_value(&val) {
|
||||
Ok(Some(s))
|
||||
} else {
|
||||
println!("the registry key HKEY_CURRENT_USER\\Environment\\PATH does not contain valid Unicode. Not modifying the PATH variable");
|
||||
return Ok(None);
|
||||
}
|
||||
}
|
||||
Err(ref e) if e.kind() == io::ErrorKind::NotFound => Ok(Some(String::new())),
|
||||
Err(e) => Err(e.to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn add_to_path(new_path: &str) -> Result<bool, String> {
|
||||
use std::ptr;
|
||||
use winapi::shared::minwindef::*;
|
||||
use winapi::um::winuser::{
|
||||
SendMessageTimeoutA, HWND_BROADCAST, SMTO_ABORTIFHUNG, WM_SETTINGCHANGE,
|
||||
};
|
||||
use winreg::enums::{RegType, HKEY_CURRENT_USER, KEY_READ, KEY_WRITE};
|
||||
use winreg::{RegKey, RegValue};
|
||||
|
||||
let old_path = if let Some(s) = get_windows_path_var()? {
|
||||
s
|
||||
} else {
|
||||
return Ok(false);
|
||||
};
|
||||
|
||||
if !old_path.contains(&new_path) {
|
||||
let mut new_path = new_path.to_string();
|
||||
if !old_path.is_empty() {
|
||||
new_path.push_str(";");
|
||||
new_path.push_str(&old_path);
|
||||
}
|
||||
|
||||
let root = RegKey::predef(HKEY_CURRENT_USER);
|
||||
let environment = root
|
||||
.open_subkey_with_flags("Environment", KEY_READ | KEY_WRITE)
|
||||
.map_err(|err| format!("Unable to open HKEY_CURRENT_USER\\Environment: {}", err))?;
|
||||
|
||||
let reg_value = RegValue {
|
||||
bytes: string_to_winreg_bytes(&new_path),
|
||||
vtype: RegType::REG_EXPAND_SZ,
|
||||
};
|
||||
|
||||
environment
|
||||
.set_raw_value("PATH", ®_value)
|
||||
.map_err(|err| format!("Unable set HKEY_CURRENT_USER\\Environment\\PATH: {}", err))?;
|
||||
|
||||
// Tell other processes to update their environment
|
||||
unsafe {
|
||||
SendMessageTimeoutA(
|
||||
HWND_BROADCAST,
|
||||
WM_SETTINGCHANGE,
|
||||
0 as WPARAM,
|
||||
"Environment\0".as_ptr() as LPARAM,
|
||||
SMTO_ABORTIFHUNG,
|
||||
5000,
|
||||
ptr::null_mut(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
println!(
|
||||
"\n{}\n {}\n\n{}",
|
||||
style("The HKEY_CURRENT_USER/Environment/PATH registry key has been modified to include:").bold(),
|
||||
new_path,
|
||||
style("Future applications will automatically have the correct environment, but you may need to restart your current shell.").bold()
|
||||
);
|
||||
Ok(true)
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
fn add_to_path(new_path: &str) -> Result<bool, String> {
|
||||
let shell_export_string = format!(r#"export PATH="{}:$PATH""#, new_path);
|
||||
let mut modified_rcfiles = false;
|
||||
|
||||
// Look for sh, bash, and zsh rc files
|
||||
let mut rcfiles = vec![dirs::home_dir().map(|p| p.join(".profile"))];
|
||||
if let Ok(shell) = std::env::var("SHELL") {
|
||||
if shell.contains("zsh") {
|
||||
let zdotdir = std::env::var("ZDOTDIR")
|
||||
.ok()
|
||||
.map(PathBuf::from)
|
||||
.or_else(dirs::home_dir);
|
||||
let zprofile = zdotdir.map(|p| p.join(".zprofile"));
|
||||
rcfiles.push(zprofile);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(bash_profile) = dirs::home_dir().map(|p| p.join(".bash_profile")) {
|
||||
// Only update .bash_profile if it exists because creating .bash_profile
|
||||
// will cause .profile to not be read
|
||||
if bash_profile.exists() {
|
||||
rcfiles.push(Some(bash_profile));
|
||||
}
|
||||
}
|
||||
let rcfiles = rcfiles.into_iter().filter_map(|f| f.filter(|f| f.exists()));
|
||||
|
||||
// For each rc file, append a PATH entry if not already present
|
||||
for rcfile in rcfiles {
|
||||
if !rcfile.exists() {
|
||||
continue;
|
||||
}
|
||||
|
||||
fn read_file(path: &Path) -> io::Result<String> {
|
||||
let mut file = fs::OpenOptions::new().read(true).open(path)?;
|
||||
let mut contents = String::new();
|
||||
io::Read::read_to_string(&mut file, &mut contents)?;
|
||||
Ok(contents)
|
||||
}
|
||||
|
||||
match read_file(&rcfile) {
|
||||
Err(err) => {
|
||||
println!("Unable to read {:?}: {}", rcfile, err);
|
||||
}
|
||||
Ok(contents) => {
|
||||
if !contents.contains(&shell_export_string) {
|
||||
println!(
|
||||
"Adding {} to {}",
|
||||
style(&shell_export_string).italic(),
|
||||
style(rcfile.to_str().unwrap()).bold()
|
||||
);
|
||||
|
||||
fn append_file(dest: &Path, line: &str) -> io::Result<()> {
|
||||
use std::io::Write;
|
||||
let mut dest_file = fs::OpenOptions::new()
|
||||
.write(true)
|
||||
.append(true)
|
||||
.create(true)
|
||||
.open(dest)?;
|
||||
|
||||
writeln!(&mut dest_file, "{}", line)?;
|
||||
|
||||
dest_file.sync_data()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
append_file(&rcfile, &shell_export_string).unwrap_or_else(|err| {
|
||||
format!("Unable to append to {:?}: {}", rcfile, err);
|
||||
});
|
||||
modified_rcfiles = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if modified_rcfiles {
|
||||
println!(
|
||||
"\n{}\n {}\n",
|
||||
style("Close and reopen your terminal to apply the PATH changes or run the following in your existing shell:").bold().blue(),
|
||||
shell_export_string
|
||||
);
|
||||
}
|
||||
|
||||
Ok(modified_rcfiles)
|
||||
}
|
||||
|
||||
pub fn init(
|
||||
config_file: &str,
|
||||
data_dir: &str,
|
||||
|
@ -294,96 +505,18 @@ pub fn init(
|
|||
}
|
||||
config
|
||||
};
|
||||
|
||||
update(config_file)?;
|
||||
|
||||
let mut modified_rcfiles = false;
|
||||
let shell_export_string = format!(
|
||||
r#"export PATH="{}:$PATH""#,
|
||||
config.active_release_bin_dir().to_str().unwrap()
|
||||
);
|
||||
|
||||
if !no_modify_path {
|
||||
// Look for sh, bash, and zsh rc files
|
||||
let mut rcfiles = vec![dirs::home_dir().map(|p| p.join(".profile"))];
|
||||
if let Ok(shell) = std::env::var("SHELL") {
|
||||
if shell.contains("zsh") {
|
||||
let zdotdir = std::env::var("ZDOTDIR")
|
||||
.ok()
|
||||
.map(PathBuf::from)
|
||||
.or_else(dirs::home_dir);
|
||||
let zprofile = zdotdir.map(|p| p.join(".zprofile"));
|
||||
rcfiles.push(zprofile);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(bash_profile) = dirs::home_dir().map(|p| p.join(".bash_profile")) {
|
||||
// Only update .bash_profile if it exists because creating .bash_profile
|
||||
// will cause .profile to not be read
|
||||
if bash_profile.exists() {
|
||||
rcfiles.push(Some(bash_profile));
|
||||
}
|
||||
}
|
||||
let rcfiles = rcfiles.into_iter().filter_map(|f| f.filter(|f| f.exists()));
|
||||
|
||||
// For each rc file, append a PATH entry if not already present
|
||||
for rcfile in rcfiles {
|
||||
if !rcfile.exists() {
|
||||
continue;
|
||||
}
|
||||
|
||||
fn read_file(path: &Path) -> io::Result<String> {
|
||||
let mut file = fs::OpenOptions::new().read(true).open(path)?;
|
||||
let mut contents = String::new();
|
||||
io::Read::read_to_string(&mut file, &mut contents)?;
|
||||
Ok(contents)
|
||||
}
|
||||
|
||||
match read_file(&rcfile) {
|
||||
Err(err) => {
|
||||
println!("Unable to read {:?}: {}", rcfile, err);
|
||||
}
|
||||
Ok(contents) => {
|
||||
if !contents.contains(&shell_export_string) {
|
||||
println!(
|
||||
"Adding {} to {}",
|
||||
style(&shell_export_string).italic(),
|
||||
style(rcfile.to_str().unwrap()).bold()
|
||||
);
|
||||
|
||||
fn append_file(dest: &Path, line: &str) -> io::Result<()> {
|
||||
use std::io::Write;
|
||||
let mut dest_file = fs::OpenOptions::new()
|
||||
.write(true)
|
||||
.append(true)
|
||||
.create(true)
|
||||
.open(dest)?;
|
||||
|
||||
writeln!(&mut dest_file, "{}", line)?;
|
||||
|
||||
dest_file.sync_data()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
append_file(&rcfile, &shell_export_string).unwrap_or_else(|err| {
|
||||
format!("Unable to append to {:?}: {}", rcfile, err);
|
||||
});
|
||||
modified_rcfiles = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if modified_rcfiles {
|
||||
println!(
|
||||
"\n{}\n {}\n",
|
||||
style("Close and reopen your terminal to apply the PATH changes or run the following in your existing shell:").bold().blue(),
|
||||
shell_export_string
|
||||
);
|
||||
let path_modified = if !no_modify_path {
|
||||
add_to_path(&config.active_release_bin_dir().to_str().unwrap())?
|
||||
} else {
|
||||
false
|
||||
};
|
||||
|
||||
if !path_modified {
|
||||
check_env_path_for_bin_dir(&config);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -394,6 +527,11 @@ pub fn info(config_file: &str, local_info_only: bool) -> Result<Option<UpdateMan
|
|||
"Update manifest pubkey:",
|
||||
&config.update_manifest_pubkey.to_string(),
|
||||
);
|
||||
println_name_value("Configuration:", &config_file);
|
||||
println_name_value(
|
||||
"Active release directory:",
|
||||
&config.active_release_dir().to_str().unwrap_or("?"),
|
||||
);
|
||||
|
||||
fn print_update_manifest(update_manifest: &UpdateManifest) {
|
||||
let when = Local.timestamp(update_manifest.timestamp_secs as i64, 0);
|
||||
|
|
Loading…
Reference in New Issue