Last active
November 18, 2019 16:50
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// +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