feat(dll): 自 go-hua 迁入 Windows 系统 API 封装

- 互斥体防多开/ShellExecute/窗口类名与标题查询/顶层窗口目录, 新增依赖 lxn/win
- 仅 Windows, 附测试、examples/dll 例程与包 README
This commit is contained in:
2026-09-20 12:29:36 +08:00
parent a4920a6a8e
commit ef7cd3e3c4
7 changed files with 390 additions and 0 deletions
+71
View File
@@ -0,0 +1,71 @@
//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("打开不存在的互斥体应返回错误")
}
}