Detect missing WebView2 at startup, show download link
Checks Windows registry for WebView2 Runtime before Tauri initializes. If missing, shows a native MessageBox explaining the requirement and opens the Microsoft download page.
This commit is contained in:
@@ -22,4 +22,4 @@ chrono = "0.4"
|
|||||||
anyhow = "1"
|
anyhow = "1"
|
||||||
|
|
||||||
[target.'cfg(windows)'.dependencies]
|
[target.'cfg(windows)'.dependencies]
|
||||||
winapi = { version = "0.3", features = ["winuser", "sysinfoapi", "windef"] }
|
winapi = { version = "0.3", features = ["winuser", "sysinfoapi", "windef", "winreg", "shellapi"] }
|
||||||
|
|||||||
@@ -2,5 +2,87 @@
|
|||||||
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
|
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
#[cfg(windows)]
|
||||||
|
if !webview2_check::is_webview2_installed() {
|
||||||
|
webview2_check::show_missing_dialog();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
core_cooldown_lib::run()
|
core_cooldown_lib::run()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(windows)]
|
||||||
|
mod webview2_check {
|
||||||
|
use std::ptr;
|
||||||
|
use winapi::shared::minwindef::{HKEY, MAX_PATH};
|
||||||
|
use winapi::um::winnt::{KEY_READ, REG_SZ};
|
||||||
|
use winapi::um::winreg::{RegOpenKeyExW, RegQueryValueExW, RegCloseKey, HKEY_LOCAL_MACHINE, HKEY_CURRENT_USER};
|
||||||
|
use winapi::um::winuser::{MessageBoxW, MB_OK, MB_ICONWARNING};
|
||||||
|
use winapi::um::shellapi::ShellExecuteW;
|
||||||
|
|
||||||
|
const WEBVIEW2_GUID: &str = r"SOFTWARE\WOW6432Node\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BEB-E15AB5810CD5}";
|
||||||
|
const WEBVIEW2_GUID_USER: &str = r"Software\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BEB-E15AB5810CD5}";
|
||||||
|
|
||||||
|
fn to_wide(s: &str) -> Vec<u16> {
|
||||||
|
s.encode_utf16().chain(std::iter::once(0)).collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn check_registry_key(root: HKEY, subkey: &str) -> bool {
|
||||||
|
unsafe {
|
||||||
|
let subkey_w = to_wide(subkey);
|
||||||
|
let value_name = to_wide("pv");
|
||||||
|
let mut hkey: HKEY = ptr::null_mut();
|
||||||
|
|
||||||
|
let status = RegOpenKeyExW(root, subkey_w.as_ptr(), 0, KEY_READ, &mut hkey);
|
||||||
|
if status != 0 {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut data = [0u16; MAX_PATH];
|
||||||
|
let mut data_size = (data.len() * 2) as u32;
|
||||||
|
let mut data_type = 0u32;
|
||||||
|
|
||||||
|
let status = RegQueryValueExW(
|
||||||
|
hkey,
|
||||||
|
value_name.as_ptr(),
|
||||||
|
ptr::null_mut(),
|
||||||
|
&mut data_type,
|
||||||
|
data.as_mut_ptr() as *mut u8,
|
||||||
|
&mut data_size,
|
||||||
|
);
|
||||||
|
|
||||||
|
RegCloseKey(hkey);
|
||||||
|
|
||||||
|
if status != 0 || data_type != REG_SZ {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert to string and check it's not empty or "0.0.0.0"
|
||||||
|
let len = (data_size as usize / 2).saturating_sub(1); // exclude null terminator
|
||||||
|
let version = String::from_utf16_lossy(&data[..len]);
|
||||||
|
!version.is_empty() && version != "0.0.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_webview2_installed() -> bool {
|
||||||
|
check_registry_key(HKEY_LOCAL_MACHINE, WEBVIEW2_GUID)
|
||||||
|
|| check_registry_key(HKEY_CURRENT_USER, WEBVIEW2_GUID_USER)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn show_missing_dialog() {
|
||||||
|
let title = to_wide("Core Cooldown - WebView2 Required");
|
||||||
|
let message = to_wide(
|
||||||
|
"Microsoft WebView2 Runtime is required to run Core Cooldown, \
|
||||||
|
but it was not found on this system.\n\n\
|
||||||
|
Click OK to open the download page in your browser.\n\n\
|
||||||
|
After installing WebView2, restart Core Cooldown."
|
||||||
|
);
|
||||||
|
let url = to_wide("https://developer.microsoft.com/en-us/microsoft-edge/webview2/consumer");
|
||||||
|
let open = to_wide("open");
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
MessageBoxW(ptr::null_mut(), message.as_ptr(), title.as_ptr(), MB_OK | MB_ICONWARNING);
|
||||||
|
ShellExecuteW(ptr::null_mut(), open.as_ptr(), url.as_ptr(), ptr::null(), ptr::null(), 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user