diff --git a/Cargo.lock b/Cargo.lock index 013e3db..bb5f797 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -519,6 +519,7 @@ dependencies = [ "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "structopt 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", "ttyecho 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 6bd52dc..f999a8c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,3 +15,4 @@ serde_json = { version = "1.0.40", features = ["preserve_order"] } dirs = "2.0.2" ttyecho = "0.1.2" structopt = "0.2.18" +winapi = { version = "0.3.7", features = ["winuser"] } \ No newline at end of file diff --git a/src/command.rs b/src/command.rs index a851151..c6665fb 100644 --- a/src/command.rs +++ b/src/command.rs @@ -1,8 +1,22 @@ use std::io::{ stdin }; +#[cfg(target_os = "linux")] use std::fs; use std::process::{ exit }; use crate::switch::{ SwitchRegistry, SwitchCategory }; +#[cfg(target_os = "linux")] use ttyecho::{ ttyecho }; +#[cfg(target_os = "windows")] +use winapi::{ + um::{ + winreg::{ RegOpenKeyExA, RegSetValueExA, RegCloseKey, HKEY_CURRENT_USER, LSTATUS }, + winuser:: { SendMessageTimeoutA, HWND_BROADCAST, WM_SETTINGCHANGE, SMTO_ABORTIFHUNG }, + winnt::{ KEY_ALL_ACCESS, REG_SZ } + }, + shared::{ + minwindef::{ HKEY }, + winerror::{ ERROR_SUCCESS } + } +}; pub fn set(registry: &mut SwitchRegistry, category_name: String, name: String, value: String) { let category = registry.get_category(&category_name); @@ -72,25 +86,61 @@ pub fn apply(registry: &mut SwitchRegistry, mut category_name: String , mut name let category = registry.get_category(&category_name); - match category { - Some(category) => { - let pts = match fs::canonicalize("/proc/self/fd/0") { - Ok(pts) => pts, - Err(why) => panic!("Could not retrieve pty: {:#?}", why) - }; + #[cfg(target_os = "windows")] + { + match category { + Some(category) => { + match category.get_variable(&name) { + Some(env) => { + unsafe { + let mut hkey: HKEY = std::ptr::null_mut(); + let env_var_reg_key = "Environment"; + let status: LSTATUS = RegOpenKeyExA(HKEY_CURRENT_USER, env_var_reg_key.as_ptr() as *const i8, 0, KEY_ALL_ACCESS, &mut hkey); - match category.get_variable(&name) { - Some(env) => { - ttyecho(pts.to_str().unwrap().to_string(), format!("export {} && clear", env.value), true); - println!("Environment variables from category '{}' applied!", category_name); - } - _ => { - eprintln!("Could not find environment variable with name '{}' in category '{}'", &name, &category_name); + if status == ERROR_SUCCESS as i32 { + let status = RegSetValueExA(hkey, env.key.as_ptr() as *const i8, 0, REG_SZ, env.value.as_ptr(), env.value.len() as u32); + RegCloseKey(hkey); + + if status == ERROR_SUCCESS as i32 { + let status = SendMessageTimeoutA(HWND_BROADCAST, WM_SETTINGCHANGE, 0, "Environment".as_ptr() as isize, SMTO_ABORTIFHUNG, 1000, std::ptr::null_mut()); + println!("Environment variable set!"); + } + } + } + } + _ => { + eprintln!("Could not find environment variable with name '{}' in category '{}'", &name, &category_name); + } } - }; - }, - None => { - eprintln!("Given category name is not registered!"); + } + _ => { + eprintln!("Given category name is not registered!"); + } + } + + } + #[cfg(target_os = "linux")] + { + match category { + Some(category) => { + let pts = match fs::canonicalize("/proc/self/fd/0") { + Ok(pts) => pts, + Err(why) => panic!("Could not retrieve pty: {:#?}", why) + }; + + match category.get_variable(&name) { + Some(env) => { + ttyecho(pts.to_str().unwrap().to_string(), format!("export {} && clear", env.value), true); + println!("Environment variables from category '{}' applied!", category_name); + } + _ => { + eprintln!("Could not find environment variable with name '{}' in category '{}'", &name, &category_name); + } + }; + }, + None => { + eprintln!("Given category name is not registered!"); + } } } }