- 互斥体防多开/ShellExecute/窗口类名与标题查询/顶层窗口目录, 新增依赖 lxn/win - 仅 Windows, 附测试、examples/dll 例程与包 README
72 lines
1.7 KiB
Go
72 lines
1.7 KiB
Go
//go:build windows
|
|
|
|
package dll
|
|
|
|
import (
|
|
"fmt"
|
|
"syscall"
|
|
"testing"
|
|
)
|
|
|
|
func TestCreateMutex(t *testing.T) {
|
|
name := fmt.Sprintf("go-hua-test-mutex-%d", syscall.Getpid())
|
|
|
|
handle, err := CreateMutex(true, name)
|
|
if err != nil {
|
|
t.Fatalf("CreateMutex: %v", err)
|
|
}
|
|
if handle == 0 {
|
|
t.Fatal("CreateMutex 句柄不应为 0")
|
|
}
|
|
syscall.CloseHandle(handle)
|
|
|
|
// 重复创建同名互斥体(不持有)应成功且不报错
|
|
handle2, err := CreateMutex(false, name)
|
|
if err != nil {
|
|
t.Errorf("重复 CreateMutex 不应报错: %v", err)
|
|
}
|
|
if handle2 != 0 {
|
|
syscall.CloseHandle(handle2)
|
|
}
|
|
}
|
|
|
|
func TestReleaseMutex(t *testing.T) {
|
|
pid := syscall.Getpid()
|
|
|
|
// 创建并持有 → 释放应成功(ReleaseMutex 传句柄值)
|
|
handle, err := CreateMutex(true, fmt.Sprintf("go-hua-release-mutex-%d", pid))
|
|
if err != nil {
|
|
t.Fatalf("CreateMutex: %v", err)
|
|
}
|
|
defer syscall.CloseHandle(handle)
|
|
|
|
if !ReleaseMutex(handle) {
|
|
t.Error("持有者 ReleaseMutex 应返回 true")
|
|
}
|
|
|
|
// 另一个未持有的互斥体 → 释放应失败
|
|
// 注意:同名互斥体重复创建会返回 183(Windows 正常行为),故使用不同名称
|
|
handle2, err := CreateMutex(false, fmt.Sprintf("go-hua-release-mutex2-%d", pid))
|
|
if err != nil {
|
|
t.Fatalf("CreateMutex: %v", err)
|
|
}
|
|
defer syscall.CloseHandle(handle2)
|
|
if ReleaseMutex(handle2) {
|
|
t.Error("未持有者 ReleaseMutex 应返回 false")
|
|
}
|
|
}
|
|
|
|
func TestReleaseMutexInvalidHandle(t *testing.T) {
|
|
// 无效句柄释放应失败且不崩溃
|
|
if ReleaseMutex(0) {
|
|
t.Error("ReleaseMutex(0) 应返回 false")
|
|
}
|
|
}
|
|
|
|
func TestOpenMutexNonExist(t *testing.T) {
|
|
_, err := OpenMutex(false, "go-hua-not-exist-mutex-xyz")
|
|
if err == nil {
|
|
t.Error("打开不存在的互斥体应返回错误")
|
|
}
|
|
}
|