Search code examples
windowsgoerror-handlinglocalization

How to get Windows system error code when calling windows API in Go


I am using windows service manager package golang.org\x..\windows\svc\mgr in Go. When calling the OpenService of this package, I am receiving the error message The specified service does not exist as an installed service. and not the windows system error code which is 1060 in this case https://learn.microsoft.com/en-us/windows/win32/debug/system-error-codes--1000-1299-

Here's the code

package service

import (
    "fmt"
    "os"
    "os/signal"
    "strconv"
    "strings"
    "sync"
    "time"
    "unsafe"

    "golang.org/x/sys/windows/registry"
    "golang.org/x/sys/windows/svc"
    "golang.org/x/sys/windows/svc/eventlog"
    "golang.org/x/sys/windows/svc/mgr"
)

func (ws *windowsService) Status() (Status, error) {
    m, err := mgr.Connect()
    if err != nil {
        return StatusUnknown, err
    }
    defer m.Disconnect()

    s, err := m.OpenService(ws.Name)
    if err != nil {
        if err.Error() == "The specified service does not exist as an installed service." {
            return StatusUnknown, ErrNotInstalled
        }
        return StatusUnknown, err
    }

    // Rest of the code.
}

The err.Error() returns only the error message so the above code works if the windows returns the error message in English language. But it fails if the English resources are not present in the OS as the error message will be returned in different language.

When executing the sc query servicename in the command prompt, it returns the error code along with the message. Example.

So, how to get the windows system error code too along with error message in Go?


Solution

  • You can do a type assertion to syscall.Errno. This will then let you handle it as if it was an int value.

    Example:

    if syserr, ok := err.(syscall.Errno); ok {
        if syserr == 1060 {
            //Do whatever
        }
    }