wails
wails copied to clipboard
Integrated Single Process Option of Wails app
Describe the solution you'd like
Currently wails does not have integrated option to make sure only 1 process is running at a time. Pls consider add this feature to wails. Thx.
In the meantime, you can do something like this, not sure if it is a good method, but it seem to work for me.
// Create a mutex to keep a program running on single instance. Return error if program is already running.
func CreateMutex(name string) (uintptr, error) {
kernel32 := syscall.NewLazyDLL("kernel32.dll")
procCreateMutex := kernel32.NewProc("CreateMutexW")
ret, _, err := procCreateMutex.Call(0, 0, uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(name))))
switch int(err.(syscall.Errno)) {
case 0:
return ret, nil
default:
return ret, err
}
}
Call the function in the main.go just before app := NewApp().
import (
sysWindows "golang.org/x/sys/windows"
)
// Create mutex to keep app running in single instance
if _, mutexErr := CreateMutex("YourAppName"); mutexErr != nil {
// Do whatever... for me, I call a messagebox...
sysWindows.MessageBox(
sysWindows.GetShellWindow(),
syscall.StringToUTF16Ptr("Application is already running!"),
syscall.StringToUTF16Ptr("Warning"),
sysWindows.MB_OK|sysWindows.MB_ICONEXCLAMATION|sysWindows.MB_SYSTEMMODAL) //See https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-messageboxw for details
os.Exit(0) //Exit if the program is already running
}
I'd love to integrate this into the options as a callback. Thoughts?
file locks is one of ways to go https://github.com/postfinance/single
There's another way making this on windows - Events. This way your first process will know that new process is launched, and, for eaxample, bring your main window to front instead of openning second process.
CreateEventW SetEvent WaitForSingleObject
It will look something like this (in C, but porting it to Go is pretty straightforward):
HANDLE hEvent = CreateEventW(nullptr, false, false, L"Global\<appname>");
if (GetLastError() == ERROR_ALREADY_EXISTS) {
// If process is already running, fire event and exit
SetEvent(hEvent);
CloseHandle(hEvent);
ExitProcess(0);
}
// If no processes is running, just wait for events
while (true) {
DWORD result = WaitForSingleObject(hEvent, INFINITE);
if (result == WAIT_OBJECT_0) {
// New process is launched
// Bring your main window to front or show a message
}
}
This has been implemented as a v3 plugin. Windows + Mac currently supported. EDIT: Linux too.