Reputation: 615
say i have the following code, using syscall
to hide command line window
process := exec.Command(name, args...)
process.SysProcAttr = &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
Upvotes: 17
Views: 15398
Reputation: 5582
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 "github.com/gonutz/w32/v2"
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.
Upvotes: 4
Reputation: 2631
Instead of hiding the console window, you should be able to prevent it with:
cmd := exec.Command(...)
cmd.SysProcAttr = &syscall.SysProcAttr{CreationFlags: 0x08000000} // CREATE_NO_WINDOW
Upvotes: 7
Reputation: 386
There is a better solution, which can run exec.Command()
without spawn a visible window, ( ͡° ͜ʖ ͡°).
Here is my code:
Firstly import "syscall"
cmd_path := "C:\\Windows\\system32\\cmd.exe"
cmd_instance := exec.Command(cmd_path, "/c", "notepad")
cmd_instance.SysProcAttr = &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/
Upvotes: 27