为了账号安全,请及时绑定邮箱和手机立即绑定

是否可以在运行时检测Go二进制文件是否使用-H=windowsgui编译

是否可以在运行时检测Go二进制文件是否使用-H=windowsgui编译

Go
千巷猫影 2023-08-07 10:36:02
-tray我构建了一个工具,如果在启动时传递了标志,则可以从控制台运行或在系统托盘中运行。仅在没有构建标志的情况下运行go build <list of go files>将创建一个可以在系统托盘中运行的二进制文件,但它也会生成一个控制台窗口。如果我传递构建标志-H=windowsgui,那么控制台窗口将被隐藏,但我仍然需要传递-tray它才能在系统托盘中实际运行。有没有一种方法可以在运行时检测二进制文件是否是使用该标志构建的,-H=windowsgui以便我可以自动执行正确的操作并启用托盘,而无需-tray传递该标志?
查看完整描述

1 回答

?
莫回无

TA贡献1865条经验 获得超7个赞

根据Go源码,它似乎是在链接时设置SubsystemOptionalHeader

因此,您可以使用debug/pe来获取它。

it is windows GUI以下代码将在使用 编译时打印go build -ldflags "-H windowsgui",否则打印it is windows CUI

请注意,os.Executable()可能会返回符号链接的路径,因此可能不可靠。

package main


import (

    "debug/pe"

    "fmt"

    "os"

)


// these constants are copied from https://github.com/golang/go/blob/6219b48e11f36329de801f62f18448bb4b1cd1a5/src/cmd/link/internal/ld/pe.go#L92-L93  

const (

    IMAGE_SUBSYSTEM_WINDOWS_GUI = 2

    IMAGE_SUBSYSTEM_WINDOWS_CUI = 3

)


func main() {

    fileName, err := os.Executable()

    if err != nil {

        panic(err)

    }

    fl, err := pe.Open(fileName)

    if err != nil {

        panic(err) // maybe not windows binary, or unreadable for some reasons

    }

    defer fl.Close()


    var subsystem uint16

    if header, ok := fl.OptionalHeader.(*pe.OptionalHeader64); ok {

        subsystem = header.Subsystem

    } else if header, ok := fl.OptionalHeader.(*pe.OptionalHeader32); ok {

        subsystem = header.Subsystem

    }


    if subsystem == IMAGE_SUBSYSTEM_WINDOWS_GUI {

        fmt.Println("it is windows GUI")

    } else if subsystem == IMAGE_SUBSYSTEM_WINDOWS_CUI {

        fmt.Println("it is windows CUI")

    } else {

        fmt.Println("binary type unknown")

    }

}


查看完整回答
反对 回复 2023-08-07
  • 1 回答
  • 0 关注
  • 100 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信