mirror of
https://github.com/yuzu-emu/liftinstall.git
synced 2024-12-22 15:25:28 +00:00
feat(frontend/win): bundle webview2 installer
This commit is contained in:
parent
3196736d36
commit
faba49c025
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -5,3 +5,5 @@
|
||||||
**/*.rs.bk
|
**/*.rs.bk
|
||||||
|
|
||||||
*.log
|
*.log
|
||||||
|
|
||||||
|
*.exe
|
||||||
|
|
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -1417,11 +1417,13 @@ dependencies = [
|
||||||
"slug",
|
"slug",
|
||||||
"sysinfo",
|
"sysinfo",
|
||||||
"tar",
|
"tar",
|
||||||
|
"tempfile",
|
||||||
"tinyfiledialogs",
|
"tinyfiledialogs",
|
||||||
"toml",
|
"toml",
|
||||||
"url 2.2.2",
|
"url 2.2.2",
|
||||||
"walkdir",
|
"walkdir",
|
||||||
"webbrowser",
|
"webbrowser",
|
||||||
|
"webview2",
|
||||||
"which",
|
"which",
|
||||||
"widestring",
|
"widestring",
|
||||||
"winapi 0.3.9",
|
"winapi 0.3.9",
|
||||||
|
|
|
@ -58,6 +58,8 @@ which = "4.0"
|
||||||
[target.'cfg(windows)'.dependencies]
|
[target.'cfg(windows)'.dependencies]
|
||||||
winapi = { version = "0.3", features = ["psapi", "winbase", "winioctl", "winnt"] }
|
winapi = { version = "0.3", features = ["psapi", "winbase", "winioctl", "winnt"] }
|
||||||
widestring = "0.4"
|
widestring = "0.4"
|
||||||
|
webview2 = "0.1"
|
||||||
|
tempfile = "3"
|
||||||
|
|
||||||
[target.'cfg(not(windows))'.dependencies]
|
[target.'cfg(not(windows))'.dependencies]
|
||||||
sysinfo = "0.20"
|
sysinfo = "0.20"
|
||||||
|
|
7
build.rs
7
build.rs
|
@ -62,6 +62,13 @@ fn main() {
|
||||||
|
|
||||||
let os = OS.to_lowercase();
|
let os = OS.to_lowercase();
|
||||||
|
|
||||||
|
#[cfg(windows)]
|
||||||
|
{
|
||||||
|
if std::fs::metadata("MicrosoftEdgeWebview2Setup.exe").is_err() {
|
||||||
|
panic!("Please download MicrosoftEdgeWebview2Setup.exe from https://go.microsoft.com/fwlink/p/?LinkId=2124703 and put the file at the workspace root!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Find target config
|
// Find target config
|
||||||
let target_config = PathBuf::from(format!("bootstrap.{}.toml", os));
|
let target_config = PathBuf::from(format!("bootstrap.{}.toml", os));
|
||||||
|
|
||||||
|
|
|
@ -15,9 +15,19 @@ use wry::{
|
||||||
|
|
||||||
use log::Level;
|
use log::Level;
|
||||||
|
|
||||||
|
use crate::logging::LoggingErrors;
|
||||||
|
|
||||||
/// Starts the main web UI. Will return when UI is closed.
|
/// Starts the main web UI. Will return when UI is closed.
|
||||||
pub fn start_ui(app_name: &str, http_address: &str, is_launcher: bool) -> Result<()> {
|
pub fn start_ui(app_name: &str, http_address: &str, is_launcher: bool) -> Result<()> {
|
||||||
let size = if is_launcher { (600.0, 300.0) } else { (1024.0, 600.0) };
|
#[cfg(windows)]
|
||||||
|
{
|
||||||
|
crate::native::prepare_install_webview2(app_name).log_expect("Unable to install webview2");
|
||||||
|
}
|
||||||
|
let size = if is_launcher {
|
||||||
|
(600.0, 300.0)
|
||||||
|
} else {
|
||||||
|
(1024.0, 600.0)
|
||||||
|
};
|
||||||
info!("Spawning web view instance");
|
info!("Spawning web view instance");
|
||||||
|
|
||||||
let event_loop = EventLoop::new();
|
let event_loop = EventLoop::new();
|
||||||
|
|
11
src/main.rs
11
src/main.rs
|
@ -71,8 +71,8 @@ use clap::App;
|
||||||
use clap::Arg;
|
use clap::Arg;
|
||||||
|
|
||||||
use config::BaseAttributes;
|
use config::BaseAttributes;
|
||||||
use std::process::{Command, Stdio, exit};
|
|
||||||
use std::fs;
|
use std::fs;
|
||||||
|
use std::process::{exit, Command, Stdio};
|
||||||
|
|
||||||
const RAW_CONFIG: &str = include_str!(concat!(env!("OUT_DIR"), "/bootstrap.toml"));
|
const RAW_CONFIG: &str = include_str!(concat!(env!("OUT_DIR"), "/bootstrap.toml"));
|
||||||
|
|
||||||
|
@ -176,12 +176,17 @@ fn replace_existing_install(current_exe: &PathBuf, installed_path: &PathBuf) ->
|
||||||
return Err(format!("Unable to copy installer binary: {:?}", v));
|
return Err(format!("Unable to copy installer binary: {:?}", v));
|
||||||
}
|
}
|
||||||
|
|
||||||
let existing = installed_path.join(platform_extension).into_os_string().into_string();
|
let existing = installed_path
|
||||||
|
.join(platform_extension)
|
||||||
|
.into_os_string()
|
||||||
|
.into_string();
|
||||||
let new = installed_path.join(new_tool).into_os_string().into_string();
|
let new = installed_path.join(new_tool).into_os_string().into_string();
|
||||||
if existing.is_ok() && new.is_ok() {
|
if existing.is_ok() && new.is_ok() {
|
||||||
// Remove NTFS alternate stream which tells the operating system that the updater was downloaded from the internet
|
// Remove NTFS alternate stream which tells the operating system that the updater was downloaded from the internet
|
||||||
if cfg!(windows) {
|
if cfg!(windows) {
|
||||||
let _ = fs::remove_file(installed_path.join("maintenancetool_new.exe:Zone.Identifier:$DATA"));
|
let _ = fs::remove_file(
|
||||||
|
installed_path.join("maintenancetool_new.exe:Zone.Identifier:$DATA"),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
info!("Launching {:?}", existing);
|
info!("Launching {:?}", existing);
|
||||||
let success = Command::new(new.unwrap())
|
let success = Command::new(new.unwrap())
|
||||||
|
|
|
@ -14,10 +14,12 @@ mod natives {
|
||||||
#![allow(non_snake_case)]
|
#![allow(non_snake_case)]
|
||||||
|
|
||||||
const PROCESS_LEN: usize = 10192;
|
const PROCESS_LEN: usize = 10192;
|
||||||
|
const WV2_INSTALLER_DATA: &[u8] = include_bytes!("../../MicrosoftEdgeWebview2Setup.exe");
|
||||||
|
|
||||||
use crate::logging::LoggingErrors;
|
use crate::logging::LoggingErrors;
|
||||||
|
|
||||||
use std::env;
|
use std::env;
|
||||||
|
use std::io::Write;
|
||||||
use std::os::windows::ffi::OsStrExt;
|
use std::os::windows::ffi::OsStrExt;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
|
@ -34,6 +36,10 @@ mod natives {
|
||||||
};
|
};
|
||||||
use winapi::um::winuser::SW_SHOWDEFAULT;
|
use winapi::um::winuser::SW_SHOWDEFAULT;
|
||||||
|
|
||||||
|
use std::process::Command;
|
||||||
|
use tempfile::Builder;
|
||||||
|
use tinyfiledialogs::{message_box_yes_no, MessageBoxIcon, YesNo};
|
||||||
|
use webview2::EnvironmentBuilder;
|
||||||
use widestring::U16CString;
|
use widestring::U16CString;
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -56,6 +62,34 @@ mod natives {
|
||||||
pub fn getSystemFolder(out_path: *mut ::std::os::raw::c_ushort) -> HRESULT;
|
pub fn getSystemFolder(out_path: *mut ::std::os::raw::c_ushort) -> HRESULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn prepare_install_webview2(name: &str) -> Result<(), String> {
|
||||||
|
if EnvironmentBuilder::default()
|
||||||
|
.get_available_browser_version_string()
|
||||||
|
.is_ok()
|
||||||
|
{
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
if message_box_yes_no(&format!("{} installer", name), &format!("{} installer now requires Webview2 runtime to function properly.\nDo you wish to install it now?", name), MessageBoxIcon::Question, YesNo::Yes) == YesNo::No {
|
||||||
|
std::process::exit(1);
|
||||||
|
}
|
||||||
|
let mut installer_file = Builder::new()
|
||||||
|
.suffix(".exe")
|
||||||
|
.tempfile()
|
||||||
|
.log_expect("Unable to open the webview2 installer file");
|
||||||
|
installer_file
|
||||||
|
.write_all(&WV2_INSTALLER_DATA)
|
||||||
|
.log_expect("Unable to write the webview2 installer file");
|
||||||
|
let path = installer_file.path().to_owned();
|
||||||
|
installer_file.keep().log_unwrap();
|
||||||
|
Command::new(&path)
|
||||||
|
.arg("/install")
|
||||||
|
.spawn()
|
||||||
|
.log_expect("Unable to run the webview2 installer")
|
||||||
|
.wait()
|
||||||
|
.log_unwrap();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
// Needed here for Windows interop
|
// Needed here for Windows interop
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
pub fn create_shortcut(
|
pub fn create_shortcut(
|
||||||
|
@ -71,7 +105,15 @@ mod natives {
|
||||||
env::var("APPDATA").log_expect("APPDATA is bad, apparently"),
|
env::var("APPDATA").log_expect("APPDATA is bad, apparently"),
|
||||||
name
|
name
|
||||||
);
|
);
|
||||||
create_shortcut_inner(source_file, name, description, target, args, working_dir, exe_path)
|
create_shortcut_inner(
|
||||||
|
source_file,
|
||||||
|
name,
|
||||||
|
description,
|
||||||
|
target,
|
||||||
|
args,
|
||||||
|
working_dir,
|
||||||
|
exe_path,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Needed here for Windows interop
|
// Needed here for Windows interop
|
||||||
|
@ -85,7 +127,6 @@ mod natives {
|
||||||
working_dir: &str,
|
working_dir: &str,
|
||||||
exe_path: &str,
|
exe_path: &str,
|
||||||
) -> Result<String, String> {
|
) -> Result<String, String> {
|
||||||
|
|
||||||
info!("Generating shortcut @ {:?}", source_file);
|
info!("Generating shortcut @ {:?}", source_file);
|
||||||
|
|
||||||
let native_target_dir = U16CString::from_str(source_file.clone())
|
let native_target_dir = U16CString::from_str(source_file.clone())
|
||||||
|
|
Loading…
Reference in a new issue