如何在使用Golang的Exec时隐藏命令提示符窗口?

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

How to hide command prompt window when using Exec in Golang?

问题

你好!以下是你要翻译的内容:

假设我有以下代码,使用syscall来隐藏命令行窗口:

process := exec.Command(name, args...)
process.SysProcAttr = &syscall.SysProcAttr{HideWindow: true}
err := process.Start()
if err != nil {
    log.Print(err)
}

但是当我编译并在Windows上运行它时,命令行窗口又出现了。

我该怎么做才能防止命令行窗口出现?

PS:我已经知道如何将Golang源代码编译为Windows GUI可执行文件,使用go build -ldflags -H=windowsgui,但这只能确保程序本身不会弹出命令行窗口,Exec仍然会显示那些窗口。

英文:

say i have the following code, using syscall to hide command line window

<!-- language: go -->

process := exec.Command(name, args...)
process.SysProcAttr = &amp;syscall.SysProcAttr{HideWindow: true}
err := process.Start()
if err != nil {
    log.Print(err)
}

but when i compiled it and tried to run it in Windows, command line window showed up again

what can i do to prevent command line window from appearing?

PS i already know how to compile golang source into a Windows GUI executable using go build -ldflags -H=windowsgui, but doing so only ensures the program itself doesn't bring up a command line window, Exec will show those windows anyway

答案1

得分: 27

有一个更好的解决方案,可以在不生成可见窗口的情况下运行exec.Command(),( ͡° ͜ʖ ͡°)。

以下是我的代码:

首先导入syscall

import "syscall"

然后设置命令路径和参数:

cmd_path := "C:\\Windows\\system32\\cmd.exe"
cmd_instance := exec.Command(cmd_path, "/c", "notepad")

接下来,设置SysProcAttr属性以隐藏窗口:

cmd_instance.SysProcAttr = &syscall.SysProcAttr{HideWindow: true}

最后,可以通过cmd_instance.Output()来执行命令并获取输出:

cmd_output, err := cmd_instance.Output()

原文链接:https://www.reddit.com/r/golang/comments/2c1g3x/build_golang_app_reverse_shell_to_run_in_windows/

英文:

There is a better solution, which can run exec.Command() without spawn a visible window, ( ͡° ͜ʖ ͡°).

Here is my code:

Firstly import &quot;syscall&quot;

cmd_path := &quot;C:\\Windows\\system32\\cmd.exe&quot;
cmd_instance := exec.Command(cmd_path, &quot;/c&quot;, &quot;notepad&quot;)
cmd_instance.SysProcAttr = &amp;syscall.SysProcAttr{HideWindow: true}
cmd_output, err := cmd_instance.Output()

Origin:
https://www.reddit.com/r/golang/comments/2c1g3x/build_golang_app_reverse_shell_to_run_in_windows/

答案2

得分: 6

你可以通过以下方式来阻止隐藏控制台窗口:

cmd := exec.Command(...)
cmd.SysProcAttr = &syscall.SysProcAttr{CreationFlags: 0x08000000} // CREATE_NO_WINDOW

这样做可以防止控制台窗口被隐藏。

英文:

Instead of hiding the console window, you should be able to prevent it with:

cmd := exec.Command(...)
cmd.SysProcAttr = &amp;syscall.SysProcAttr{CreationFlags: 0x08000000} // CREATE_NO_WINDOW

答案3

得分: 5

如果使用-ldflags -H=windowsgui进行构建,每个exec.Command将会生成一个新的控制台窗口。

如果不使用该标志进行构建,你将得到一个控制台窗口,所有的exec.Command都会打印到这个窗口中。

我的当前解决方案是在不使用该标志的情况下进行构建,也就是在程序启动时有一个控制台窗口,然后在程序开始时立即使用以下代码隐藏控制台窗口:

import "github.com/gonutz/w32/v2"

func hideConsole() {
    console := w32.GetConsoleWindow()
    if console == 0 {
        return // 没有附加的控制台
    }
    // 如果该应用程序是创建控制台窗口的进程,则
    // 该程序没有使用-H=windowsgui标志进行编译,并且在启动时
    // 它会创建一个控制台以及主应用程序窗口。在这种情况下
    // 隐藏控制台窗口。
    // 参考
    // http://stackoverflow.com/questions/9009333/how-to-check-if-the-program-is-run-from-a-console
    _, consoleProcID := w32.GetWindowThreadProcessId(console)
    if w32.GetCurrentProcessId() == consoleProcID {
        w32.ShowWindowAsync(console, w32.SW_HIDE)
    }
}

关于进程ID的详细信息,请参见此线程

现在,所有的exec.Command都会将其输出打印到隐藏的控制台窗口,而不是生成自己的窗口。

这种折衷的方法是,在启动程序时,你的程序会闪现一个控制台窗口,但在隐藏之前只会持续很短的时间。

英文:

If you build with -ldflags -H=windowsgui, each exec.Command will spawn a new console window.

If you build without the flag, you get one console window and all exec.Commands print into that one.

My current solution is thus to build without the flag, i.e. have a console window on program start, then immediately hide the console window with this code at the start of my program:

import &quot;github.com/gonutz/w32/v2&quot;

func hideConsole() {
	console := w32.GetConsoleWindow()
	if console == 0 {
		return // no console attached
	}
	// If this application is the process that created the console window, then
	// this program was not compiled with the -H=windowsgui flag and on start-up
	// it created a console along with the main application window. In this case
	// hide the console window.
	// See
	// http://stackoverflow.com/questions/9009333/how-to-check-if-the-program-is-run-from-a-console
	_, consoleProcID := w32.GetWindowThreadProcessId(console)
	if w32.GetCurrentProcessId() == consoleProcID {
		w32.ShowWindowAsync(console, w32.SW_HIDE)
	}
}

See this thread for the details about the process ID stuff.

What happens is that all exec.Commands now print their output to the hidden console window instead of spawning their own.

The compromise here is that your program will flash a console window once when you start it, but only for a brief moment before it goes into hiding.

huangapple
  • 本文由 发表于 2017年2月28日 13:02:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/42500570.html
匿名

发表评论

匿名网友

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

确定