Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Restricting to Single Instance of Executable with Golang

Tags:

windows

go

mutex

I need to only allow one instance of my Golang executable at a time. I'm not sure how to use a Global Mutex to make sure no other instances are running.

This would be running on a Windows Machine.

like image 697
Kevin Postal Avatar asked Apr 18 '14 21:04

Kevin Postal


2 Answers

I know this topic is a bit old, but I needed it recently on Windows and I'll post here how I did it in case someone else needs.

Thx to @VonC for pointing me in the right direction.

var (
    kernel32        = syscall.NewLazyDLL("kernel32.dll")
    procCreateMutex = kernel32.NewProc("CreateMutexW")
)

func CreateMutex(name string) (uintptr, error) {
    ret, _, err := procCreateMutex.Call(
        0,
        0,
        uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(name))),
    )
    switch int(err.(syscall.Errno)) {
    case 0:
        return ret, nil
    default:
        return ret, err
    }
}

// mutexName starting with "Global\" will work across all user sessions
_, err := CreateMutex("SomeMutexName")

I created a lib with a more complete example: https://github.com/rodolfoag/gow32

Thx!

like image 157
Rodolfo Gonçalves Avatar answered Sep 27 '22 21:09

Rodolfo Gonçalves


There doesn't seem to be a cross-platform solution (beside writing a file, and looking for that file at start time).

On Windows, this thread reports

the recommended approach (and the one that has worked great for me) is to use the CreateSemaphore function.
If the name you specify starts with "Global\", then the semaphore is unique for the entire system and a second attempt to open it will fail.

This is a kernel32 call, which has some wrapper in Go available.

kostix adds in the comments:

look at the Go source code around the pkg\syscall hierarchy -- it contains a good wealth of examples on how to call out to DLLs on Windows using syscalls (and that's how you access anything in Windows API).

That would be syscall/dll_windows.go. (And here is a gist)

The odbc package by brainman is another example of direct API calls on Windows -- possibly easier to digest.

Like api/zapi_windows.go.

like image 20
VonC Avatar answered Sep 27 '22 21:09

VonC