Repository navigation
Expand file tree
/
Copy pathsingle_instance.go
More file actions
63 lines (51 loc) · 1.8 KB
/
Copy pathsingle_instance.go
File metadata and controls
63 lines (51 loc) · 1.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
package main
import (
"unsafe"
"golang.org/x/sys/windows"
)
// ────────────────────────────────────────────────────────────
// Single instance protection via named mutex
// ────────────────────────────────────────────────────────────
const mutexName = "Global\\QRCoder_SingleInstance"
var instanceMutex windows.Handle
// acquireSingleInstance creates or opens a named mutex. Returns
// false if another instance is already running.
func acquireSingleInstance() bool {
muName, _ := windows.UTF16PtrFromString(mutexName)
handle, err := windows.CreateMutex(nil, true, muName)
if err != nil {
// If we can't create the mutex, allow the app to start
return true
}
if windows.GetLastError() == windows.ERROR_ALREADY_EXISTS {
windows.CloseHandle(handle)
// Find and bring existing instance window to foreground
bringExistingToFront()
return false
}
instanceMutex = handle
return true
}
// releaseSingleInstance releases the instance mutex.
func releaseSingleInstance() {
if instanceMutex != 0 {
windows.CloseHandle(instanceMutex)
instanceMutex = 0
}
}
// bringExistingToFront finds the existing QRCoder window and
// brings it to the foreground.
func bringExistingToFront() {
user32 := windows.NewLazySystemDLL("user32.dll")
// Find window by class name
className, _ := windows.UTF16PtrFromString(mainWndClass)
hwnd, _, _ := user32.NewProc("FindWindowW").Call(
uintptr(unsafe.Pointer(className)),
0,
)
if hwnd != 0 {
// Bring to foreground
user32.NewProc("SetForegroundWindow").Call(hwnd)
user32.NewProc("ShowWindow").Call(hwnd, 9) // SW_RESTORE = 9
}
}