How to ask for administer privileges on Windows with Go

后端 未结 2 1738
夕颜
夕颜 2021-01-31 11:08

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

相关标签:
2条回答
  • 2021-01-31 11:52

    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.

    0 讨论(0)
  • 2021-01-31 12:06

    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

    0 讨论(0)
提交回复
热议问题