Skip to content

Commit a6baeb5

Browse files
committed
Use msiexec /x for self uninstall
1 parent 705ae4e commit a6baeb5

File tree

2 files changed

+46
-0
lines changed

2 files changed

+46
-0
lines changed

Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ rustls-backend = ["download/rustls-backend"]
2828
# Include in the default set to disable self-update and uninstall.
2929
no-self-update = []
3030

31+
# Used to change behavior of self-update and uninstall if installed via MSI
32+
msi-installed = []
33+
3134
[dependencies]
3235
rustup-dist = { path = "src/rustup-dist", version = "0.5.0" }
3336
rustup-utils = { path = "src/rustup-utils", version = "0.5.0" }

src/rustup-cli/self_update.rs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -571,6 +571,19 @@ pub fn uninstall(no_prompt: bool) -> Result<()> {
571571
err!("you should probably use your system package manager to uninstall rustup");
572572
process::exit(1);
573573
}
574+
575+
if cfg!(feature = "msi-installed") {
576+
// Get the product code of the MSI installer from the registry
577+
// and spawn `msiexec /x`, then exit immediately
578+
let product_code = try!(get_msi_product_code());
579+
try!(Command::new("msiexec")
580+
.arg("/x")
581+
.arg(product_code)
582+
.spawn()
583+
.chain_err(|| ErrorKind::WindowsUninstallMadness));
584+
process::exit(0);
585+
}
586+
574587
let ref cargo_home = try!(utils::cargo_home());
575588

576589
if !cargo_home.join(&format!("bin/rustup{}", EXE_SUFFIX)).exists() {
@@ -647,6 +660,36 @@ pub fn uninstall(no_prompt: bool) -> Result<()> {
647660
process::exit(0);
648661
}
649662

663+
#[cfg(not(feature = "msi-installed"))]
664+
fn get_msi_product_code() -> Result<String> {
665+
unreachable!()
666+
}
667+
668+
#[cfg(feature = "msi-installed")]
669+
fn get_msi_product_code() -> Result<String> {
670+
use winreg::RegKey;
671+
use winapi::*;
672+
673+
let root = RegKey::predef(HKEY_CURRENT_USER);
674+
let environment = root.open_subkey_with_flags("SOFTWARE\\rustup", KEY_READ);
675+
676+
match environment {
677+
Ok(env) => {
678+
match env.get_value("InstalledProductCode") {
679+
Ok(val) => {
680+
Ok(val)
681+
}
682+
Err(e) => {
683+
Err(e).chain_err(|| ErrorKind::WindowsUninstallMadness)
684+
}
685+
}
686+
}
687+
Err(e) => {
688+
Err(e).chain_err(|| ErrorKind::WindowsUninstallMadness)
689+
}
690+
}
691+
}
692+
650693
#[cfg(unix)]
651694
fn delete_rustup_and_cargo_home() -> Result<()> {
652695
let ref cargo_home = try!(utils::cargo_home());

0 commit comments

Comments
 (0)