fix(single-instance): limit second instance's wait on Windows (#3645)

* Update windows.rs

* Create single-instance-forward-timeout.md

* use SMTO_NORMAL

* nit

---------

Co-authored-by: Lucas Nogueira <lucas@tauri.app>
This commit is contained in:
justanotheranonymoususerandLucas Nogueira authored and Lucas Nogueira committed 2026-10-09 15:25:33 -03:00
1 parent 323fe80df1
commit 818d2e04d9
2 files changed
+26 -4

No files matched your search

@@ -0,0 +1,5 @@
---
"single-instance": patch
---
On Windows, a second instance no longer waits indefinitely for a first instance that stopped processing messages: it stops waiting after 10 seconds and exits. The first instance may still receive the arguments once it resumes processing messages.
@@ -21,14 +21,17 @@ use windows_sys::Win32::{
UI::WindowsAndMessaging::{
self as w32wm, AllowSetForegroundWindow, CREATESTRUCTW, CreateWindowExW, DefWindowProcW,
DestroyWindow, FindWindowW, GWL_STYLE, GWLP_USERDATA, GetWindowThreadProcessId,
RegisterClassExW, SendMessageW, WINDOW_LONG_PTR_INDEX, WM_COPYDATA, WM_CREATE, WM_DESTROY,
WNDCLASSEXW, WS_EX_LAYERED, WS_EX_NOACTIVATE, WS_EX_TOOLWINDOW, WS_EX_TRANSPARENT,
WS_OVERLAPPED, WS_POPUP, WS_VISIBLE,
RegisterClassExW, SMTO_NORMAL, SendMessageTimeoutW, WINDOW_LONG_PTR_INDEX, WM_COPYDATA,
WM_CREATE, WM_DESTROY, WNDCLASSEXW, WS_EX_LAYERED, WS_EX_NOACTIVATE, WS_EX_TOOLWINDOW,
WS_EX_TRANSPARENT, WS_OVERLAPPED, WS_POPUP, WS_VISIBLE,
},
};
const WMCOPYDATA_SINGLE_INSTANCE_DATA: usize = 1542;
/// How long the second instance waits for the first instance to take its arguments.
const FORWARD_TIMEOUT_MS: u32 = 10_000;
struct MutexHandle(isize);
struct TargetWindowHandle(isize);
@@ -102,7 +105,21 @@ pub fn init<R: Runtime>(callback: Box<SingleInstanceCallback<R>>) -> TauriPlugin
lpData: bytes.as_ptr() as _,
};
SendMessageW(hwnd, WM_COPYDATA, 0, &cds as *const _ as _);
let sent = SendMessageTimeoutW(
hwnd,
WM_COPYDATA,
0,
&cds as *const _ as _,
SMTO_NORMAL,
FORWARD_TIMEOUT_MS,
std::ptr::null_mut(),
);
if sent == 0 {
tracing::warn!(
"single_instance failed to forward arguments to the running instance within {FORWARD_TIMEOUT_MS}ms (error {})",
GetLastError()
);
}
app.cleanup_before_exit();
std::process::exit(0);