Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion src-tauri/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,25 @@ fn main() {
// 确保目录存在
let _ = std::fs::create_dir_all(&webview_data_dir);
std::env::set_var("WEBVIEW2_USER_DATA_FOLDER", &webview_data_dir);

// 检测已缓存的 WebView2 固定版本运行时
// 验证目录包含关键文件以确保运行时完整可用
let webview2_runtime_dir = exe_dir.join("webview2_runtime");
if webview2_runtime_dir.is_dir()
&& webview2_runtime_dir.join("msedgewebview2.exe").exists()
{
std::env::set_var(
"WEBVIEW2_BROWSER_EXECUTABLE_FOLDER",
&webview2_runtime_dir,
);
}
}
}

if !webview2::ensure_webview2() {
// 已有本地运行时时跳过检测,否则检测系统安装或自动下载
if std::env::var_os("WEBVIEW2_BROWSER_EXECUTABLE_FOLDER").is_none()
&& !webview2::ensure_webview2()
{
std::process::exit(1);
}

Expand Down
38 changes: 33 additions & 5 deletions src-tauri/src/webview2/dialog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,15 @@ struct DialogState {
status_hwnd: Option<HWND>,
button_hwnd: Option<HWND>,
hfont: Option<HGDIOBJ>,
dialog_type: Option<DialogType>,
}

impl DialogState {
fn clear(&mut self) {
self.progress_hwnd = None;
self.status_hwnd = None;
self.button_hwnd = None;
self.dialog_type = None;
}
}

Expand Down Expand Up @@ -90,7 +92,17 @@ unsafe extern "system" fn dialog_wnd_proc(
}
LRESULT(0)
}
WM_DIALOG_CLOSE | WM_CLOSE => {
WM_CLOSE => {
// 用户点击 X 关闭窗口:进度对话框直接退出进程(此时 Tauri 尚未启动)
DIALOG_STATE.with(|s| {
if s.borrow().dialog_type == Some(DialogType::Progress) {
std::process::exit(0);
}
});
PostQuitMessage(0);
LRESULT(0)
}
WM_DIALOG_CLOSE => {
PostQuitMessage(0);
LRESULT(0)
}
Expand Down Expand Up @@ -216,23 +228,35 @@ impl CustomDialog {
RegisterClassW(&wc);

let title_wide = to_wide(&title_owned);
let wnd_style = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU;
// width/height represent desired client area; compute actual window size
let mut rc = windows::Win32::Foundation::RECT {
left: 0,
top: 0,
right: width,
bottom: height,
};
let _ = AdjustWindowRect(&mut rc, wnd_style, false);
let wnd_w = rc.right - rc.left;
let wnd_h = rc.bottom - rc.top;

let hwnd = CreateWindowExW(
WINDOW_EX_STYLE::default(),
PCWSTR::from_raw(class_name.as_ptr()),
PCWSTR::from_raw(title_wide.as_ptr()),
WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU,
wnd_style,
CW_USEDEFAULT,
CW_USEDEFAULT,
width,
height,
wnd_w,
wnd_h,
None,
None,
hinstance,
None,
)
.unwrap_or_default();

center_window(hwnd, width, height);
center_window(hwnd, wnd_w, wnd_h);

const MARGIN: i32 = 24;
const BTN_W: i32 = 96;
Expand Down Expand Up @@ -279,6 +303,7 @@ impl CustomDialog {
let mut g = s.borrow_mut();
g.status_hwnd = Some(status_hwnd);
g.progress_hwnd = Some(progressbar_hwnd);
g.dialog_type = Some(dialog_type);
});
}
DialogType::Success | DialogType::Error => {
Expand Down Expand Up @@ -380,6 +405,9 @@ impl CustomDialog {
}

pub(crate) fn set_status(&self, text: &str) {
// 安全说明:wide_text 分配在栈上,其指针通过 LPARAM 传递给 UI 线程。
// 这里必须使用 SendMessageW(同步)而非 PostMessageW(异步),
// 因为 SendMessageW 会阻塞直到消息处理完成,确保 wide_text 在被使用期间有效。
let wide_text = to_wide(text);
unsafe {
let _ = SendMessageW(
Expand Down
Loading
Loading