44 lines
1.0 KiB
Go
44 lines
1.0 KiB
Go
//go:build windows
|
|
|
|
package instance
|
|
|
|
import (
|
|
"errors"
|
|
|
|
"golang.org/x/sys/windows"
|
|
)
|
|
|
|
type windowsInstanceLock struct {
|
|
handle windows.Handle
|
|
}
|
|
|
|
// tryAcquireInstanceLock 用共享模式为 0 的 CreateFile 独占锁文件:
|
|
// 已被占用的锁文件会返回 ERROR_SHARING_VIOLATION,此时调用方继续扫描下一个槽位。
|
|
func tryAcquireInstanceLock(path string) (instanceLock, bool, error) {
|
|
handle, err := windows.CreateFile(
|
|
windows.StringToUTF16Ptr(path),
|
|
windows.GENERIC_READ|windows.GENERIC_WRITE,
|
|
0,
|
|
nil,
|
|
windows.OPEN_ALWAYS,
|
|
windows.FILE_ATTRIBUTE_NORMAL,
|
|
0,
|
|
)
|
|
if err != nil {
|
|
if errors.Is(err, windows.ERROR_SHARING_VIOLATION) || errors.Is(err, windows.ERROR_ACCESS_DENIED) {
|
|
return nil, false, nil
|
|
}
|
|
return nil, false, err
|
|
}
|
|
return &windowsInstanceLock{handle: handle}, true, nil
|
|
}
|
|
|
|
func (l *windowsInstanceLock) Close() error {
|
|
if l == nil || l.handle == windows.InvalidHandle {
|
|
return nil
|
|
}
|
|
err := windows.CloseHandle(l.handle)
|
|
l.handle = windows.InvalidHandle
|
|
return err
|
|
}
|