How to ask for administer privileges on Windows with Go

huangapple go评论80阅读模式
英文:

How to ask for administer privileges on Windows with Go

问题

我想要实现的是,每次运行应用程序时都不需要右键点击并选择“以管理员身份运行”。我希望Windows能像其他Windows应用程序一样提示我获取管理员权限。

考虑以下代码:

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

如果你编译并双击运行它,会打印出以下信息:

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

但是,如果你右键点击并选择以管理员身份运行,它将创建并写入文件。

如何使其在双击时请求管理员权限呢?

英文:

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?

答案1

得分: 20

你需要嵌入一个清单文件,告诉Windows你想要提升的权限。

该页面上的示例代码如下:

<?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>

这个go-nuts帖子建议使用rsrc可以帮助你解决问题。

英文:

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

The example from that page is:

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

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

答案2

得分: 20

这是我用来检测是否以管理员身份运行的技术,如果不是,则重新以UAC提示框的方式启动自己。这样我就可以在大多数情况下以标准用户身份运行,只有在需要时才提升权限。我在命令行工具中使用这个技术,其中大多数功能不需要管理员权限,但像-install或-uninstall这样的功能需要,因为它们要写入注册表或程序文件中的HKLM。使用这种方法不需要清单文件。

更多详细信息请参考:
https://gist.github.com/jerblack/d0eb182cc5a1c1d92d92a4c4fcc416c6

英文:

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 (
	&quot;fmt&quot;
	&quot;golang.org/x/sys/windows&quot;
	&quot;os&quot;
	&quot;syscall&quot;
	&quot;time&quot;
)

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

}

func runMeElevated() {
	verb := &quot;runas&quot;
	exe, _ := os.Executable()
	cwd, _ := os.Getwd()
	args := strings.Join(os.Args[1:], &quot; &quot;)
	
	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(&quot;\\\\.\\PHYSICALDRIVE0&quot;)
	if err != nil {
		fmt.Println(&quot;admin no&quot;)
		return false
	}
	fmt.Println(&quot;admin yes&quot;)
	return true
}

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

huangapple
  • 本文由 发表于 2015年7月22日 16:38:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/31558066.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定