gpt4 book ai didi

go - 使用 -ldflags -H=windowsgui 编译 golang 应用程序时将输出打印到命令窗口

转载 作者:IT老高 更新时间:2023-10-28 13:06:56 38 4
gpt4 key购买 nike

我有一个通常在后台静默运行的应用程序,所以我用它来编译它

go build -ldflags -H=windowsgui <gofile>

要在命令行检查版本,我想将 -V 标志传递给命令行,以获取保存要打印到命令提示符的版本的字符串,然后让应用程序退出。我添加了标志包和代码。当我用

测试它时
go run <gofile> -V

...它可以很好地打印版本。当我编译 exe 时,它​​只是退出,什么也不打印。我怀疑这是编译标志导致它无法访问控制台并将我的文本发送到位桶。

我尝试了使用 println、fprintf 和 os.stderr.write 打印到 stderr 和 stdout 的变体,但编译后的应用程序中没有显示任何内容。使用这些标志编译时,我应该如何尝试将字符串打印到命令提示符?

最佳答案

问题在于,当使用具有 the "subsystem" variable 的可执行文件创建进程时在其PE header设置为“Windows”,进程有它的three standard handles关闭并且它不与任何控制台关联——无论您是否从控制台运行它。 (事实上​​,如果您从控制台运行一个其子系统设置为“console”not 的可执行文件,则会为该进程强制创建一个控制台并将该进程附加到它上——您通常会看到它作为一个突然弹出的控制台窗口。)

因此,要从 Windows 上的 GUI 进程将任何内容打印到控制台,您必须将该进程显式连接到附加到其父进程(如果有的话)的控制台,如 here 所述例如。为此,请调用 AttachConsole API函数。使用 Go,这可以使用 syscall 包来完成:

package main

import (
"fmt"
"syscall"
)

const (
ATTACH_PARENT_PROCESS = ^uint32(0) // (DWORD)-1
)

var (
modkernel32 = syscall.NewLazyDLL("kernel32.dll")

procAttachConsole = modkernel32.NewProc("AttachConsole")

)

func AttachConsole(dwParentProcess uint32) (ok bool) {
r0, _, _ := syscall.Syscall(procAttachConsole.Addr(), 1, uintptr(dwParentProcess), 0, 0)
ok = bool(r0 != 0)
return
}

func main() {
ok := AttachConsole(ATTACH_PARENT_PROCESS)
if ok {
fmt.Println("Okay, attached")
}
}

要真正完整,当 AttachConsole() 失败时,此代码可能应该采用以下两种途径之一:

  • 调用 AllocConsole() 为它创建自己的控制台窗口。

    可以说这对于显示版本信息几乎没有用,因为该过程通常在打印后退出,由此产生的用户体验将是一个控制台窗口弹出并立即消失;高级用户会得到提示,他们应该从控制台重新运行应用程序,但普通人可能无法应付。

  • 发布一个显示相同信息的 GUI 对话框。

    我认为这正是我们所需要的:请注意,显示帮助/使用消息以响应用户指定一些命令行参数通常与控制台在心理上相关,但这不是要遵循的教条:例如,尝试在控制台上运行 msiexec.exe/? 看看会发生什么。

关于go - 使用 -ldflags -H=windowsgui 编译 golang 应用程序时将输出打印到命令窗口,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23743217/

38 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com