Fix Windows file handoff when single-instance mode is enabled (#12944)

Fix Windows single-instance file handoff

On Windows, opening a model file while OrcaSlicer is already running could
fail when single-instance mode was enabled.

The second launch correctly detected that another instance already existed,
but it could no longer find the running main window to forward the file-open
request. As a result, the new process exited and the file was dropped.

This happened because the existing-instance lookup depended on the native
window title containing "OrcaSlicer". After the titlebar change from #12706,
the title may contain only the project name, so the running instance was no
longer discoverable that way.

Fix this by identifying the existing main window through stable window
properties instead of title text:
- require the expected wxWidgets window class
- require the instance hash properties to exist
- match against the current instance hash

This restores forwarding of externally opened files to the already-running
instance without depending on the current titlebar text.
This commit is contained in:
Kiss Lorand
2026-05-14 19:57:52 +03:00
committed by GitHub
parent 291b34a8fd
commit 69594fa586

View File

@@ -87,45 +87,39 @@ namespace instance_check_internal
#ifdef _WIN32
static HWND l_bambu_studio_hwnd;
static HWND orca_slicer_hwnd;
static BOOL CALLBACK EnumWindowsProc(_In_ HWND hwnd, _In_ LPARAM lParam)
{
//checks for other instances of prusaslicer, if found brings it to front and return false to stop enumeration and quit this instance
//search is done by classname(wxWindowNR is wxwidgets thing, so probably not unique) and name in window upper panel
//other option would be do a mutex and check for its existence
//BOOST_LOG_TRIVIAL(error) << "ewp: version: " << l_version_wstring;
TCHAR wndText[1000];
TCHAR className[1000];
int err;
err = GetClassName(hwnd, className, 1000);
if (err == 0)
// ORCA: Find the already-running instance by its window properties
TCHAR className[256]; // class names are limited to 255 characters, see https://learn.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-wndclassa
if (GetClassName(hwnd, className, 256) == 0)
return true;
err = GetWindowText(hwnd, wndText, 1000);
if (err == 0)
if (std::wstring(className) != L"wxWindowNR")
return true;
std::wstring classNameString(className);
std::wstring wndTextString(wndText);
if (wndTextString.find(L"OrcaSlicer") != std::wstring::npos && classNameString == L"wxWindowNR") {
//check if other instances has same instance hash
//if not it is not same version(binary) as this version
HANDLE handle = GetProp(hwnd, L"Instance_Hash_Minor");
uint64_t other_instance_hash = PtrToUint(handle);
uint64_t other_instance_hash_major;
uint64_t my_instance_hash = GUI::wxGetApp().get_instance_hash_int();
handle = GetProp(hwnd, L"Instance_Hash_Major");
other_instance_hash_major = PtrToUint(handle);
other_instance_hash_major = other_instance_hash_major << 32;
other_instance_hash += other_instance_hash_major;
if(my_instance_hash == other_instance_hash)
{
BOOST_LOG_TRIVIAL(debug) << "win enum - found correct instance";
l_bambu_studio_hwnd = hwnd;
ShowWindow(hwnd, SW_SHOWMAXIMIZED);
SetForegroundWindow(hwnd);
return false;
}
BOOST_LOG_TRIVIAL(debug) << "win enum - found wrong instance";
// Check if the candidate window has the same instance hash. If the
// properties are missing, it is not an OrcaSlicer main window.
HANDLE handle_minor = GetProp(hwnd, L"Instance_Hash_Minor");
HANDLE handle_major = GetProp(hwnd, L"Instance_Hash_Major");
if (handle_minor == nullptr || handle_major == nullptr)
return true;
uint64_t other_instance_hash = PtrToUint(handle_minor);
uint64_t other_instance_hash_major = PtrToUint(handle_major);
other_instance_hash_major = other_instance_hash_major << 32;
other_instance_hash += other_instance_hash_major;
uint64_t my_instance_hash = GUI::wxGetApp().get_instance_hash_int();
if (my_instance_hash == other_instance_hash) {
BOOST_LOG_TRIVIAL(debug) << "win enum - found correct instance";
orca_slicer_hwnd = hwnd;
ShowWindow(hwnd, SW_SHOWMAXIMIZED);
SetForegroundWindow(hwnd);
return false;
}
BOOST_LOG_TRIVIAL(debug) << "win enum - found wrong instance";
return true;
}
static bool send_message(const std::string& message, const std::string &version)
@@ -145,7 +139,7 @@ namespace instance_check_internal
data_to_send.dwData = 1;
data_to_send.cbData = sizeof(TCHAR) * (wcslen(*command_line_args.get()) + 1);
data_to_send.lpData = *command_line_args.get();
SendMessage(l_bambu_studio_hwnd, WM_COPYDATA, 0, (LPARAM)&data_to_send);
SendMessage(orca_slicer_hwnd, WM_COPYDATA, 0, (LPARAM)&data_to_send);
return true;
}
return false;