猿问

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

-tray我构建了一个工具,如果在启动时传递了标志,则可以从控制台运行或在系统托盘中运行。仅在没有构建标志的情况下运行go build <list of go files>将创建一个可以在系统托盘中运行的二进制文件,但它也会生成一个控制台窗口。如果我传递构建标志-H=windowsgui,那么控制台窗口将被隐藏,但我仍然需要传递-tray它才能在系统托盘中实际运行。

有没有一种方法可以在运行时检测二进制文件是否是使用该标志构建的,-H=windowsgui以便我可以自动执行正确的操作并启用托盘,而无需-tray传递该标志?


千巷猫影
浏览 101回答 1
1回答

莫回无

根据Go源码,它似乎是在链接时设置Subsystem的OptionalHeader。因此,您可以使用debug/pe来获取它。it is windows GUI以下代码将在使用 编译时打印go build -ldflags "-H windowsgui",否则打印it is windows CUI。请注意,os.Executable()可能会返回符号链接的路径,因此可能不可靠。package mainimport (    "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")    }}
随时随地看视频慕课网APP

相关分类

Go
我要回答