From 08bc6159576e2e6009330fe831a6f2c4fcf9793e Mon Sep 17 00:00:00 2001 From: James Date: Sat, 15 Dec 2018 19:14:25 +1100 Subject: [PATCH] Ensure that the updater isn't conflicting with an already running process --- Cargo.lock | 76 +++++++++++++++++++++++++++++++ Cargo.toml | 2 + src/main.rs | 2 + src/tasks/ensure_only_instance.rs | 58 +++++++++++++++++++++++ src/tasks/install.rs | 8 +++- src/tasks/install_dir.rs | 2 +- src/tasks/mod.rs | 1 + 7 files changed, 147 insertions(+), 2 deletions(-) create mode 100644 src/tasks/ensure_only_instance.rs diff --git a/Cargo.lock b/Cargo.lock index fb2256e..5ba3bc9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -155,6 +155,15 @@ dependencies = [ "build_const 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "crossbeam-deque" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "crossbeam-deque" version = "0.6.1" @@ -164,6 +173,20 @@ dependencies = [ "crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "crossbeam-epoch" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "crossbeam-epoch" version = "0.5.2" @@ -177,6 +200,14 @@ dependencies = [ "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "crossbeam-utils" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "crossbeam-utils" version = "0.5.0" @@ -196,6 +227,11 @@ name = "dtoa" version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "either" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "encoding_rs" version = "0.8.6" @@ -475,6 +511,7 @@ dependencies = [ "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", + "sysinfo 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "tar 0.4.16 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -865,6 +902,27 @@ name = "rand_core" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "rayon" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rayon-core 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rayon-core" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "redox_syscall" version = "0.1.40" @@ -1108,6 +1166,17 @@ dependencies = [ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "sysinfo" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "rayon 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "take" version = "0.1.0" @@ -1648,11 +1717,15 @@ dependencies = [ "checksum core-foundation 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "286e0b41c3a20da26536c6000a280585d519fd07b3956b43aed8a79e9edce980" "checksum core-foundation-sys 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "716c271e8613ace48344f723b60b900a93150271e5be206212d052bbc0883efa" "checksum crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d663548de7f5cca343f1e0a48d14dcfb0e9eb4e079ec58883b7251539fa10aeb" +"checksum crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f739f8c5363aca78cfb059edf753d8f0d36908c348f3d8d1503f03d8b75d9cf3" "checksum crossbeam-deque 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3486aefc4c0487b9cb52372c97df0a48b8c249514af1ee99703bf70d2f2ceda1" +"checksum crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "927121f5407de9956180ff5e936fe3cf4324279280001cd56b669d28ee7e9150" "checksum crossbeam-epoch 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "30fecfcac6abfef8771151f8be4abc9e4edc112c2bcb233314cafde2680536e9" +"checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9" "checksum crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "677d453a17e8bd2b913fa38e8b9cf04bcdbb5be790aa294f2389661d72036015" "checksum dirs 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f679c09c1cf5428702cc10f6846c56e4e23420d3a88bcc9335b17c630a7b710b" "checksum dtoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6d301140eb411af13d3115f9a562c85cc6b541ade9dfa314132244aaee7489dd" +"checksum either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3be565ca5c557d7f59e7cfcf1844f9e3033650c929c6566f511e8005f205c1d0" "checksum encoding_rs 0.8.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2a91912d6f37c6a8fef8a2316a862542d036f13c923ad518b5aca7bcaac7544c" "checksum fern 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "57915fe00a83af935983eb2d00b0ecc62419c4741b28c207ecbf98fd4a1b94c8" "checksum filetime 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "da4b9849e77b13195302c174324b5ba73eec9b236b24c221a61000daefb95c5f" @@ -1725,6 +1798,8 @@ dependencies = [ "checksum rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8356f47b32624fef5b3301c1be97e5944ecdd595409cc5da11d05f211db6cfbd" "checksum rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e464cd887e869cddcae8792a4ee31d23c7edd516700695608f5b98c67ee0131c" "checksum rand_core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "edecf0f94da5551fc9b492093e30b041a891657db7940ee221f9d2f66e82eef2" +"checksum rayon 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "373814f27745b2686b350dd261bfd24576a6fb0e2c5919b3a2b6005f820b0473" +"checksum rayon-core 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b055d1e92aba6877574d8fe604a63c8b5df60f60e5982bf7ccbb1338ea527356" "checksum redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "c214e91d3ecf43e9a4e41e578973adeb14b474f2bee858742d127af75a0112b1" "checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" "checksum regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9329abc99e39129fcceabd24cf5d85b4671ef7c29c50e972bc5afe32438ec384" @@ -1756,6 +1831,7 @@ dependencies = [ "checksum string 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00caf261d6f90f588f8450b8e1230fa0d5be49ee6140fdfbcb55335aff350970" "checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550" "checksum syn 0.15.4 (registry+https://github.com/rust-lang/crates.io-index)" = "9056ebe7f2d6a38bc63171816fd1d3430da5a43896de21676dc5c0a4b8274a11" +"checksum sysinfo 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4c747a1fbe091faa7bf76c19f40099f9f12495384c811485d81cf3d60c0eae62" "checksum take 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b157868d8ac1f56b64604539990685fa7611d8fa9e5476cf0c02cf34d32917c5" "checksum tar 0.4.16 (registry+https://github.com/rust-lang/crates.io-index)" = "e8f41ca4a5689f06998f0247fcb60da6c760f1950cc9df2a10d71575ad0b062a" "checksum tempfile 3.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "55c1195ef8513f3273d55ff59fe5da6940287a0d7a98331254397f464833675b" diff --git a/Cargo.toml b/Cargo.toml index c8bac8f..e56d219 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -38,6 +38,8 @@ chrono = "0.4.5" clap = "2.32.0" +sysinfo = "*" + [build-dependencies] walkdir = "2" serde = "1.0.27" diff --git a/src/main.rs b/src/main.rs index dfffb1f..e18a9af 100644 --- a/src/main.rs +++ b/src/main.rs @@ -41,6 +41,8 @@ extern crate chrono; extern crate clap; +extern crate sysinfo; + mod archives; mod assets; mod config; diff --git a/src/tasks/ensure_only_instance.rs b/src/tasks/ensure_only_instance.rs new file mode 100644 index 0000000..47a97ad --- /dev/null +++ b/src/tasks/ensure_only_instance.rs @@ -0,0 +1,58 @@ +//! Verifies that this is the only running instance of the installer, and that no application is running. + +use installer::InstallerFramework; + +use tasks::Task; +use tasks::TaskDependency; +use tasks::TaskMessage; +use tasks::TaskParamType; + +use sysinfo; +use sysinfo::get_current_pid; +use sysinfo::ProcessExt; +use sysinfo::SystemExt; + +pub struct EnsureOnlyInstanceTask {} + +impl Task for EnsureOnlyInstanceTask { + fn execute( + &mut self, + input: Vec, + context: &mut InstallerFramework, + _messenger: &Fn(&TaskMessage), + ) -> Result { + assert_eq!(input.len(), 0); + + let system = sysinfo::System::new(); + let current_pid = get_current_pid(); + for (pid, process) in system.get_process_list() { + if pid == ¤t_pid { + continue; + } + + let exe = process.exe(); + + if exe.ends_with("maintenancetool.exe") || exe.ends_with("maintenancetool") { + return Err(format!("Maintenance tool is already running!")); + } + + for package in &context.database.packages { + for file in &package.files { + if exe.ends_with(file) { + return Err(format!("The installed application is currently running!")); + } + } + } + } + + Ok(TaskParamType::None) + } + + fn dependencies(&self) -> Vec { + vec![] + } + + fn name(&self) -> String { + format!("EnsureOnlyInstanceTask") + } +} diff --git a/src/tasks/install.rs b/src/tasks/install.rs index 6f1574e..47562f7 100644 --- a/src/tasks/install.rs +++ b/src/tasks/install.rs @@ -2,12 +2,13 @@ use installer::InstallerFramework; +use tasks::ensure_only_instance::EnsureOnlyInstanceTask; use tasks::install_dir::VerifyInstallDirTask; +use tasks::install_global_shortcut::InstallGlobalShortcutsTask; use tasks::install_pkg::InstallPackageTask; use tasks::save_executable::SaveExecutableTask; use tasks::uninstall_pkg::UninstallPackageTask; -use tasks::install_global_shortcut::InstallGlobalShortcutsTask; use tasks::Task; use tasks::TaskDependency; use tasks::TaskMessage; @@ -34,6 +35,11 @@ impl Task for InstallTask { fn dependencies(&self) -> Vec { let mut elements = Vec::new(); + elements.push(TaskDependency::build( + TaskOrdering::Pre, + Box::new(EnsureOnlyInstanceTask {}), + )); + elements.push(TaskDependency::build( TaskOrdering::Pre, Box::new(VerifyInstallDirTask { diff --git a/src/tasks/install_dir.rs b/src/tasks/install_dir.rs index c8e4c53..d5d8f93 100644 --- a/src/tasks/install_dir.rs +++ b/src/tasks/install_dir.rs @@ -44,7 +44,7 @@ impl Task for VerifyInstallDirTask { .map_err(|x| format!("Failed to read install destination: {:?}", x))?; if paths.count() != 0 { - return Err(format!("Install destination ({:?}) is not empty.", context.install_path)); + return Err(format!("Install destination ({:?}) is not empty.", path)); } } diff --git a/src/tasks/mod.rs b/src/tasks/mod.rs index 51c399e..614c841 100644 --- a/src/tasks/mod.rs +++ b/src/tasks/mod.rs @@ -10,6 +10,7 @@ use sources::types::File; use sources::types::Version; pub mod download_pkg; +pub mod ensure_only_instance; pub mod install; pub mod install_dir; pub mod install_global_shortcut;