- Printing version of the utility if started with special flag (like -V)
- Program needs complicated tune up through the command line arguments or configuration file, but normally is running on the background. It would be beneficially to have a choice either run it with console or run it quietly.
// taken from: http://www.codeproject.com/KB/dialog/ConsoleAdapter.aspx AllocConsole(); int fdout = _open_osfhandle((long)GetStdHandle(STD_OUTPUT_HANDLE), _O_TEXT); FILE* fout = _fdopen(fdout, "w"); *stdout = *fout; int fdin = _open_osfhandle((long)GetStdHandle(STD_INPUT_HANDLE), _O_TEXT); FILE* fin = _fdopen(fdin, "r"); *stdin = *fin;
Nowadays I found myself programming more and more in Go. While initially Go compiler was intended for Linux only, that is not the case anymore. Windows now is the first class citizen in the Go world. Recently I needed to create application, which may open the console if that demanded by command line argument, but work invisibly otherwise . To my surprise there were not that many online information how to do that in Go. I did find one answered question in StackOverflow. Alas, proposed solution did not work for me out of the box. But using it as starting point and after some googling I have found workable solution. Here is sample of Go application, which will allocate console, print some prompt, wait for keyboard input and quit.
// go build -ldflags -H=windowsgui package main import "fmt" import "os" import "syscall" func main() { modkernel32 := syscall.NewLazyDLL("kernel32.dll") procAllocConsole := modkernel32.NewProc("AllocConsole") r0, r1, err0 := syscall.Syscall(procAllocConsole.Addr(), 0, 0, 0, 0) if r0 == 0 { // Allocation failed, probably process already has a console fmt.Printf("Could not allocate console: %s. Check build flags..", err0) os.Exit(1) } hout, err1 := syscall.GetStdHandle(syscall.STD_OUTPUT_HANDLE) hin, err2 := syscall.GetStdHandle(syscall.STD_INPUT_HANDLE) if err1 != nil || err2 != nil { // nowhere to print the error os.Exit(2) } os.Stdout = os.NewFile(uintptr(hout), "/dev/stdout") os.Stdin = os.NewFile(uintptr(hin), "/dev/stdin") fmt.Printf("Hello!\nResult of console allocation: ") fmt.Printf("r0=%d,r1=%d,err=%s\nFor Goodbye press Enter..", r0, r1, err0) var s string fmt.Scanln(&s) os.Exit(0) }
- This function has five arguments. It is different of what you will find in the online Go Doc . Looks like doc references Linux definition, which is not the same as Windows.
- Second parameter here is number of arguments in dll function. For our case it is 0.
- Function returns three variables, but only first is really meaningful. It is the result returned by AllocConsole function. Second variables always 0. Third variables is an error, but in cannot be analyzed in the regular Go way as far as it is never nil. Still it could be useful: in case of success its value is different from value on failure (for example if application was build with no windowsgui flag and already has the console ) .
No comments:
Post a Comment