feat(dll): 自 go-hua 迁入 Windows 系统 API 封装
- 互斥体防多开/ShellExecute/窗口类名与标题查询/顶层窗口目录, 新增依赖 lxn/win - 仅 Windows, 附测试、examples/dll 例程与包 README
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user