mirror of
https://github.com/alterware/alterware-launcher.git
synced 2025-12-04 07:17:50 +00:00
use winget to install redists
This commit is contained in:
40
Cargo.lock
generated
40
Cargo.lock
generated
@@ -31,7 +31,6 @@ dependencies = [
|
|||||||
"openssl",
|
"openssl",
|
||||||
"rand 0.9.0",
|
"rand 0.9.0",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"runas",
|
|
||||||
"self-replace",
|
"self-replace",
|
||||||
"semver",
|
"semver",
|
||||||
"serde",
|
"serde",
|
||||||
@@ -326,12 +325,6 @@ dependencies = [
|
|||||||
"windows-sys 0.48.0",
|
"windows-sys 0.48.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "either"
|
|
||||||
version = "1.13.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "encode_unicode"
|
name = "encode_unicode"
|
||||||
version = "0.3.6"
|
version = "0.3.6"
|
||||||
@@ -568,15 +561,6 @@ version = "0.3.9"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024"
|
checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "home"
|
|
||||||
version = "0.5.9"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5"
|
|
||||||
dependencies = [
|
|
||||||
"windows-sys 0.52.0",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "http"
|
name = "http"
|
||||||
version = "1.2.0"
|
version = "1.2.0"
|
||||||
@@ -1298,18 +1282,6 @@ dependencies = [
|
|||||||
"windows-sys 0.52.0",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "runas"
|
|
||||||
version = "1.2.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "b96d6b6c505282b007a9b009f2aa38b2fd0359b81a0430ceacc60f69ade4c6a0"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
"security-framework-sys",
|
|
||||||
"which",
|
|
||||||
"windows-sys 0.48.0",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustc-demangle"
|
name = "rustc-demangle"
|
||||||
version = "0.1.23"
|
version = "0.1.23"
|
||||||
@@ -2123,18 +2095,6 @@ dependencies = [
|
|||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "which"
|
|
||||||
version = "4.4.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7"
|
|
||||||
dependencies = [
|
|
||||||
"either",
|
|
||||||
"home",
|
|
||||||
"once_cell",
|
|
||||||
"rustix",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winapi"
|
name = "winapi"
|
||||||
version = "0.3.9"
|
version = "0.3.9"
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ openssl = { version = "0.10.71", default-features = false, features = ["vendored
|
|||||||
steamlocate = "=2.0.0-beta.2"
|
steamlocate = "=2.0.0-beta.2"
|
||||||
mslnk = "0.1.8"
|
mslnk = "0.1.8"
|
||||||
self-replace = "1.5.0"
|
self-replace = "1.5.0"
|
||||||
runas = "1.2.0"
|
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
winresource = "0.1.19"
|
winresource = "0.1.19"
|
||||||
|
|||||||
@@ -868,9 +868,7 @@ async fn main() {
|
|||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
if arg_bool(&args, "--redist") {
|
if arg_bool(&args, "--redist") {
|
||||||
arg_remove(&mut args, "--redist");
|
arg_remove(&mut args, "--redist");
|
||||||
misc::install_dependencies(&install_path).await;
|
misc::install_dependencies(&install_path, true).await;
|
||||||
println_info!("Redistributables installation finished. Press enter to exit...");
|
|
||||||
misc::stdin();
|
|
||||||
std::process::exit(0);
|
std::process::exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -941,7 +939,7 @@ async fn main() {
|
|||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
if !cfg.skip_redist {
|
if !cfg.skip_redist {
|
||||||
misc::install_dependencies(&install_path).await;
|
misc::install_dependencies(&install_path, false).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
127
src/misc.rs
127
src/misc.rs
@@ -54,6 +54,21 @@ pub fn is_program_in_path(program: &str) -> bool {
|
|||||||
.unwrap_or(false)
|
.unwrap_or(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(windows)]
|
||||||
|
pub fn is_program_in_path(program: &str) -> bool {
|
||||||
|
std::env::var_os("PATH")
|
||||||
|
.and_then(|paths| {
|
||||||
|
paths.to_str().map(|paths| {
|
||||||
|
paths.split(';').any(|dir| {
|
||||||
|
fs::metadata(format!("{}\\{}.exe", dir, program)).is_ok()
|
||||||
|
|| fs::metadata(format!("{}\\{}.cmd", dir, program)).is_ok()
|
||||||
|
|| fs::metadata(format!("{}\\{}.bat", dir, program)).is_ok()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.unwrap_or(false)
|
||||||
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! println_info {
|
macro_rules! println_info {
|
||||||
($($arg:tt)*) => {{
|
($($arg:tt)*) => {{
|
||||||
@@ -71,68 +86,68 @@ macro_rules! println_error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
fn install_dependency(path: &Path, args: &[&str]) {
|
pub async fn install_dependencies(_install_path: &Path, force_reinstall: bool) {
|
||||||
if path.exists() {
|
if force_reinstall {
|
||||||
match runas::Command::new(path).args(args).status() {
|
crate::println_info!("Force reinstalling redistributables...");
|
||||||
Ok(status) if status.success() || matches!(status.code(), Some(1638) | Some(3010)) => {
|
|
||||||
info!("{} installed successfully", path.display());
|
|
||||||
}
|
|
||||||
Ok(status) => {
|
|
||||||
println_error!("Error installing dependency {}, {status}", path.display());
|
|
||||||
}
|
|
||||||
Err(e) if e.raw_os_error() == Some(740) => {
|
|
||||||
println_error!(
|
|
||||||
"Error: Process requires elevation. Please run the launcher as administrator or install {} manually",
|
|
||||||
path.display()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
println_error!("Error running file {}: {e}", path.display());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
println_error!("Installer not found: {}", path.display());
|
crate::println_info!("Installing redistributables...");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
if !is_program_in_path("winget") {
|
||||||
#[cfg(windows)]
|
crate::println_info!(
|
||||||
async fn download_and_install_dependency(url: &str, path: &Path, args: &[&str]) {
|
"winget is not available. Unable to install redistributables automatically."
|
||||||
if !path.exists() {
|
);
|
||||||
info!("Downloading {} from {url}", path.display());
|
crate::println_info!(
|
||||||
if let Some(parent) = path.parent() {
|
"Please install Visual C++ Redistributables and DirectX manually if needed."
|
||||||
if let Err(e) = fs::create_dir_all(parent) {
|
);
|
||||||
println_error!("Error creating directory {}: {e}", parent.display());
|
return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
match crate::http_async::download_file(url, &std::path::PathBuf::from(path)).await {
|
|
||||||
Ok(_) => info!("Downloaded {}", path.display()),
|
|
||||||
Err(e) => {
|
|
||||||
println_error!("Error downloading {}: {e}", path.display());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
install_dependency(path, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(windows)]
|
let packages = [
|
||||||
pub async fn install_dependencies(install_path: &Path) {
|
"Microsoft.VCRedist.2005.x86",
|
||||||
println!("If you run into issues during dependency installation, open alterware-launcher.json and set \"skip_redist\" to true");
|
"Microsoft.VCRedist.2008.x86",
|
||||||
|
"Microsoft.VCRedist.2010.x86",
|
||||||
let redist_dir = install_path.join("redist\\alterware");
|
"Microsoft.VCRedist.2015+.x86",
|
||||||
let redists = [
|
"Microsoft.DirectX",
|
||||||
("VC++ 2005", "https://download.microsoft.com/download/8/B/4/8B42259F-5D70-43F4-AC2E-4B208FD8D66A/vcredist_x86.EXE", "vcredist_2005_x86.exe", &["/Q"] as &[&str]),
|
|
||||||
("VC++ 2008", "https://download.microsoft.com/download/5/D/8/5D8C65CB-C849-4025-8E95-C3966CAFD8AE/vcredist_x86.exe", "vcredist_2008_x86.exe", &["/Q"] as &[&str]),
|
|
||||||
("VC++ 2010", "https://download.microsoft.com/download/1/6/5/165255E7-1014-4D0A-B094-B6A430A6BFFC/vcredist_x86.exe", "vcredist_2010_x86.exe", &["/Q"] as &[&str]),
|
|
||||||
("VC++ 2015", "https://download.microsoft.com/download/9/3/F/93FCF1E7-E6A4-478B-96E7-D4B285925B00/vc_redist.x86.exe", "vcredist_2015_x86.exe", &["/install", "/passive", "/norestart"] as &[&str]),
|
|
||||||
("DirectX End User Runtime", "https://download.microsoft.com/download/1/7/1/1718CCC4-6315-4D8E-9543-8E28A4E18C4C/dxwebsetup.exe", "dxwebsetup.exe", &["/Q"] as &[&str]),
|
|
||||||
];
|
];
|
||||||
|
|
||||||
for (name, url, file, args) in redists.iter() {
|
for package in packages.iter() {
|
||||||
let path = redist_dir.join(file);
|
let mut args = vec![
|
||||||
println_info!("Installing {name}");
|
"install",
|
||||||
download_and_install_dependency(url, &path, args).await;
|
"--id",
|
||||||
|
package,
|
||||||
|
"--silent",
|
||||||
|
"--accept-package-agreements",
|
||||||
|
"--accept-source-agreements",
|
||||||
|
];
|
||||||
|
|
||||||
|
if force_reinstall {
|
||||||
|
args.push("--force");
|
||||||
|
}
|
||||||
|
|
||||||
|
let result = std::process::Command::new("winget")
|
||||||
|
.args(&args)
|
||||||
|
.output();
|
||||||
|
|
||||||
|
match result {
|
||||||
|
Ok(output) => {
|
||||||
|
if output.status.success() {
|
||||||
|
crate::println_info!("Successfully installed {}", package);
|
||||||
|
} else {
|
||||||
|
crate::println_info!(
|
||||||
|
"Failed to install {} (may already be installed)",
|
||||||
|
package
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(_) => {
|
||||||
|
crate::println_info!("Unable to install redistributables automatically.");
|
||||||
|
crate::println_info!(
|
||||||
|
"Please install Visual C++ Redistributables and DirectX manually if needed."
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user