Skip to content

Instantly share code, notes, and snippets.

@GrimTheReaper
Last active November 18, 2019 16:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save GrimTheReaper/b926e296614894c3da428bfbadb86065 to your computer and use it in GitHub Desktop.
Save GrimTheReaper/b926e296614894c3da428bfbadb86065 to your computer and use it in GitHub Desktop.
This package will tell you whether or not a golang application was opened in the terminal. Very useful for `fyne` or any other UI libs, when you plan on having both a GUI and a CLI. We're using this to make an app that can be used heedlessly, for the advanced users, and with a GUI using fyne so the less experienced users can use the tool too.
// +build windows
package opened
import (
"syscall"
"unsafe"
)
// <Unsafe>
var (
// TODO:
// Replace these calls with golang.org/x/sys/windows
// Right now, syscall.NewLazyDLL is subjected to potential DLL preloading
// attacks.
moduser32 = syscall.NewLazyDLL("user32.dll")
modkernel32 = syscall.NewLazyDLL("kernel32.dll")
getConsoleWindowProc = modkernel32.NewProc("GetConsoleWindow")
getCurrentProcessIDProc = modkernel32.NewProc("GetCurrentProcessId")
getWindowThreadProcessIDProc = moduser32.NewProc("GetWindowThreadProcessId")
)
func getWindowThreadProcessID(hwnd uintptr) (uintptr, uint32) {
var processID uint32
ret, _, _ := getWindowThreadProcessIDProc.Call(
hwnd,
uintptr(unsafe.Pointer(&processID)),
)
return ret, processID
}
func getCurrentProcessID() uint32 {
id, _, _ := getCurrentProcessIDProc.Call()
return uint32(id)
}
func getConsoleWindow() uintptr {
// Note:
// If you build with -ldflags -H=windowsgui
// You will need to check the error, it'll be like "The handle is invalid."
hwnd, _, _ := getConsoleWindowProc.Call()
return hwnd
}
// </Unsafe>
// WithTerminal returns if the application was opened with a terminal or with
// the desktop.
func WithTerminal() bool {
console := getConsoleWindow()
if console != 0 {
_, consoleProcID := getWindowThreadProcessID(console)
if getCurrentProcessID() == consoleProcID {
return false
}
}
return true
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment