Search code examples
windowswinapigouac

Request UAC elevation in Go


Is there any way to elevate a new process or thread to administrator in Go?

It seems like ShellExecute() isn't available in Go and it isn't possible to elevate with CreateProcess(). I have no idea what else could be possible.


Solution

  • You can try and check the project w32: it has a shell32.go ShellExecute() that could be useful.

    w32 is a wrapper of windows apis for the Go Programming Language.

    It wraps win32 apis to "Go style" to make them easier to use.


    Update 2020, since 2014, the package golang.org/x/sys/windows does have a ShellExecute() function.

    Cliven mentions Jeremy Black's blog post "Relaunch Windows Golang program with UAC elevation when admin rights needed"

    • Jeremy first detects if the program is already running as admin by attempting to open \\.\PHYSICALDRIVE0 (per this reddit suggestion)

      _, err := os.Open("\\\\.\\PHYSICALDRIVE0")
      
    • Then Jeremy uses the ShellExecute() function, to call runas (described in "Elevating During Runtime" from Michael Haephrati)

      func runMeElevated() {
          verb := "runas"
          exe, _ := os.Executable()
          cwd, _ := os.Getwd()
          args := strings.Join(os.Args[1:], " ")
      
          verbPtr, _ := syscall.UTF16PtrFromString(verb)
          exePtr, _ := syscall.UTF16PtrFromString(exe)
          cwdPtr, _ := syscall.UTF16PtrFromString(cwd)
          argPtr, _ := syscall.UTF16PtrFromString(args)
      
          var showCmd int32 = 1 //SW_NORMAL
      
          err := windows.ShellExecute(0, verbPtr, exePtr, argPtr, cwdPtr, showCmd)
          if err != nil {
              fmt.Println(err)
          }
      }