Golang 编译Win32 程序
因为工作中需要给某些.dll
文件设置所有者为everyone
,需要请求UAC
权限,故做笔记备忘。
项目初始化
mkdir app
cd app
go mod init app
管理资源文件
请求UAC
时需要设置app
的资源文件属性。
go install github.com/akavel/rsrc
# 编译资源文件,有些注意事项可以查找上面的仓库
rsrc -manifest nac.manifest -o nac.syso
go build
# 在go 1.16 开始,编译器会自动加载`.syso` 的文件并将其嵌入到二进制文件中,不需要额外指定。
nac.manifest
至于名字为什么是nac.manifest
?其实不是必须的,最好与APP 同名就好了。
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity
version="0.0.0.1"
processorArchitecture="x86"
name="app.exe"
type="win32"
/>
<description>something about your app</description>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel level="requireAdministrator" uiAccess="false"/>
</requestedPrivileges>
</security>
</trustInfo>
</assembly>
Go 代码
主要是可以通过cmd
调用icacls
命令来修改.dll
的权限。下面是递归遍历文件夹的函数:
userName = "everyone"
fileExt = ".dll"
// 递归遍历文件夹
func walkDir(dir string) {
files, err := ioutil.ReadDir(dir)
if err != nil {
println("目录不存在?")
return
}
for _, file := range files {
if file.IsDir() {
walkDir(dir + "/" + file.Name())
} else {
absPath, err := filepath.Abs(dir + "/" + file.Name())
if err != nil { fmt.Println(err) }
ext := path.Ext(absPath) // 获取文件扩展名
if strings.ToLower(ext) == fileExt {
// cmd 执行`icacls` 修改文件权限
cmd := exec.Command("icacls", absPath, "/grant", userName+":F")
_, err := cmd.CombinedOutput()
if err != nil {
println("恐怕是用户名输错了")
return
}
log.Println("成功修改:", absPath)
}
}
}
}
感谢@Arrnitage 给的问题反馈_