Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to ask for administer privileges on Windows with Go

Tags:

windows

go

What I want to achieve for my application, is to not need to right click and choose Run as administrator each time I want to run it. I want Windows to prompt me to gain admin permissions as with other windows applications.

consider the following code:

package main

import (
    "fmt"
    "io/ioutil"
    "time"
)

func main() {
    err := ioutil.WriteFile("C:/Windows/test.txt", []byte("TESTING!"), 0644)
    if err != nil {
        fmt.Println(err.Error())
        time.Sleep(time.Second * 3)
    }
}

If you compile it and double click on it it will print:

open: C:\Windows\test.txt: Access is denied.

But if you right-click and run as administrator, it will create and write the file.

How to make it ask for the admin permission just by double clicking on it?

like image 753
pyed Avatar asked Jul 22 '15 08:07

pyed


People also ask

How do I request administrator access on Windows?

You can double-click the Administrator Access icon from the desktop or left-click the green checkmark icon from the system tray and request administrator access. After making the request, type a reason for requesting administrative access and click OK. Review the code of conduct and click OK.

How do I get administrative privileges on my computer?

Type netplwiz into the Start Menu (or the Win + R Run menu) to access it. Here, you'll see a list of every user on your machine. Click one and hit the Properties button, then select the Group Membership tab. You can change an account from Standard users to Administrator.


2 Answers

You need to embed a manifest file which will tell Windows that you want elevated privileges.

The example from that page is:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity
    version="9.0.0.0"
    processorArchitecture="x86"
    name="myapp.exe"
    type="win32"
/>
<description>My App</description>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
    <security>
        <requestedPrivileges>
            <requestedExecutionLevel level="requireAdministrator" uiAccess="false"/>
        </requestedPrivileges>
    </security>
</trustInfo>
</assembly>

This go-nuts post suggests that using rsrc should do the trick for you.

like image 120
Colin Nicholson Avatar answered Sep 18 '22 20:09

Colin Nicholson


This is the technique that I use to detect if I am running as administrator, and if not relaunch myself with a UAC prompt. This allows me to run as a standard user in most cases, and only elevate when needed. I use this in command line tools where most functions don't need admin rights, but functions like -install or -uninstall do since they're writing to HKLM in the registry or Program Files. No manifest is necessary with this method.

package main

import (
    "fmt"
    "golang.org/x/sys/windows"
    "os"
    "syscall"
    "time"
)

func main() {
    // if not elevated, relaunch by shellexecute with runas verb set
    if !amAdmin() {
        runMeElevated()
    }
    time.Sleep(10*time.Second)

}

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)
    }
}

func amAdmin() bool {
    _, err := os.Open("\\\\.\\PHYSICALDRIVE0")
    if err != nil {
        fmt.Println("admin no")
        return false
    }
    fmt.Println("admin yes")
    return true
}

More details available here:
https://gist.github.com/jerblack/d0eb182cc5a1c1d92d92a4c4fcc416c6

like image 21
jerblack Avatar answered Sep 21 '22 20:09

jerblack