Files
zogo/dll/mutex.go
T
4566704 ef7cd3e3c4 feat(dll): 自 go-hua 迁入 Windows 系统 API 封装
- 互斥体防多开/ShellExecute/窗口类名与标题查询/顶层窗口目录, 新增依赖 lxn/win
- 仅 Windows, 附测试、examples/dll 例程与包 README
2026-09-20 12:29:36 +08:00

77 lines
2.1 KiB
Go

package dll
import (
"fmt"
"github.com/lxn/win"
"syscall"
"unsafe"
)
// CreateMutex 创建命名互斥体(常用于防止程序多开)
// bInitialOwner 为是否立即持有;互斥体已存在时返回错误(错误码 183)
func CreateMutex(bInitialOwner bool, mutexName string) (syscall.Handle, error) {
// 互斥体名需转为 UTF-16 指针(LPCWSTR),不能直接传 Go string 的地址
namePtr, nameErr := syscall.UTF16PtrFromString(mutexName)
if nameErr != nil {
return 0, nameErr
}
handle, _, err := syscall.SyscallN(procCreateMutexW.Addr(), 0, uintptr(win.BoolToBOOL(bInitialOwner)), uintptr(unsafe.Pointer(namePtr)))
if err != 0 {
println(err.Error())
lastError := win.GetLastError()
fmt.Println("lastError", lastError)
if lastError == 183 {
fmt.Println("Mutex 已经存在")
}
return 0, err
}
//defer syscall.CloseHandle(syscall.Handle(m))
if syscall.Handle(handle) != 0 {
lastError := win.GetLastError()
if lastError == 183 {
//fmt.Println("Mutex 已经存在")
}
}
// do something with the mutex
return syscall.Handle(handle), nil
}
// MUTANT_ALL_ACCESS 互斥体的完全访问权限
const MUTANT_ALL_ACCESS = 2031617
// OpenMutex 打开已存在的命名互斥体
func OpenMutex(bInheritHandle bool, mutexName string) (syscall.Handle, error) {
desiredAccess := MUTANT_ALL_ACCESS
handle, _, err := syscall.SyscallN(procOpenMutexW.Addr(), uintptr(desiredAccess), uintptr(win.BoolToBOOL(bInheritHandle)), uintptr(unsafe.Pointer(&mutexName)))
if err != 0 {
return 0, err
}
defer syscall.CloseHandle(syscall.Handle(handle))
if syscall.Handle(handle) == 0 {
e2 := win.GetLastError()
if e2 == 183 {
fmt.Println("打开失败")
}
fmt.Println(e2)
} // do something with the mutex
fmt.Println("Mutex open", syscall.Handle(handle))
return syscall.Handle(handle), nil
}
// ReleaseMutex 释放互斥体持有权
func ReleaseMutex(handle syscall.Handle) bool {
// 传句柄值本身,而非句柄变量的地址
ret, _, e1 := syscall.SyscallN(procReleaseMutex.Addr(), uintptr(handle))
if e1 != 0 {
println(e1.Error())
return false
}
return ret != 0
}