Skip to content

Commit c493f76

Browse files
committed
Enhance and use code to add an entry to the installed programs on windows
1 parent b1a9bf2 commit c493f76

File tree

2 files changed

+49
-6
lines changed

2 files changed

+49
-6
lines changed

src/cli/self_update.rs

+4
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,8 @@ pub fn install(
344344

345345
if !opts.no_modify_path {
346346
do_add_to_path()?;
347+
#[cfg(windows)]
348+
do_add_to_programs()?;
347349
}
348350
utils::create_rustup_home()?;
349351
maybe_install_rust(
@@ -854,6 +856,8 @@ pub fn uninstall(no_prompt: bool) -> Result<utils::ExitCode> {
854856

855857
// Remove CARGO_HOME/bin from PATH
856858
do_remove_from_path()?;
859+
#[cfg(windows)]
860+
do_remove_from_programs()?;
857861

858862
// Delete everything in CARGO_HOME *except* the rustup bin
859863

src/cli/self_update/windows.rs

+45-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::env::consts::EXE_SUFFIX;
22
use std::ffi::{OsStr, OsString};
3-
use std::os::windows::ffi::OsStrExt;
3+
use std::os::windows::ffi::{OsStrExt, OsStringExt};
44
use std::path::Path;
55
use std::process::Command;
66

@@ -282,12 +282,26 @@ pub fn do_remove_from_path() -> Result<()> {
282282
_apply_new_path(new_path)
283283
}
284284

285-
fn do_add_to_programs() -> Result<()> {
285+
pub fn do_add_to_programs() -> Result<()> {
286+
use std::path::PathBuf;
287+
286288
let key = RegKey::predef(HKEY_CURRENT_USER)
287289
.create_subkey(r"Software\Microsoft\Windows\CurrentVersion\Uninstall\rustup")
288290
.chain_err(|| ErrorKind::PermissionDenied)?
289291
.0;
290292

293+
// Don't overwrite registry if rustup is already installed
294+
let prev = key
295+
.get_raw_value("UninstallString")
296+
.map(|val| from_winreg_value(&val));
297+
if let Ok(Some(s)) = prev {
298+
let mut path = PathBuf::from(OsString::from_wide(&s));
299+
path.pop();
300+
if path.exists() {
301+
return Ok(());
302+
}
303+
}
304+
291305
let mut path = utils::cargo_home()?;
292306
path.push("bin\rustup.exe");
293307
let mut uninstall_cmd = path.into_os_string();
@@ -300,15 +314,40 @@ fn do_add_to_programs() -> Result<()> {
300314

301315
key.set_raw_value("UninstallString", &reg_value)
302316
.chain_err(|| ErrorKind::PermissionDenied)?;
303-
key.set_value("DisplayName", &"rustup")
317+
key.set_value("DisplayName", &"rustup - Rust toolchain manager")
304318
.chain_err(|| ErrorKind::PermissionDenied)?;
305319

306320
Ok(())
307321
}
308322

309-
fn do_remove_from_programs() -> Result<()> {
310-
RegKey::predef(HKEY_CURRENT_USER)
311-
.delete_subkey_all(r"Software\Microsoft\Windows\CurrentVersion\Uninstall\rustup")
323+
pub fn do_remove_from_programs() -> Result<()> {
324+
use std::io;
325+
use std::path::PathBuf;
326+
327+
let root = RegKey::predef(HKEY_CURRENT_USER);
328+
329+
let key = match root.open_subkey(r"Software\Microsoft\Windows\CurrentVersion\Uninstall\rustup")
330+
{
331+
Ok(key) => key,
332+
Err(ref e) if e.kind() == io::ErrorKind::NotFound => return Ok(()),
333+
Err(e) => return Err(e).chain_err(|| ErrorKind::PermissionDenied),
334+
};
335+
336+
// Don't remove uninstall information from another installation
337+
let cur = key
338+
.get_raw_value("UninstallString")
339+
.map(|val| from_winreg_value(&val));
340+
if let Ok(Some(s)) = cur {
341+
let mut reg_path = PathBuf::from(OsString::from_wide(&s));
342+
reg_path.pop();
343+
let mut path = utils::cargo_home()?;
344+
path.push("bin");
345+
if reg_path != path {
346+
return Ok(());
347+
}
348+
}
349+
350+
root.delete_subkey_all(r"Software\Microsoft\Windows\CurrentVersion\Uninstall\rustup")
312351
.chain_err(|| ErrorKind::PermissionDenied)
313352
}
314353

0 commit comments

Comments
 (0)