1 // Based on ssh/terminal:
2 // Copyright 2011 The Go Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file.
6 // +build windows,!appengine
22 var kernel32 = syscall.NewLazyDLL("kernel32.dll")
25 procGetConsoleMode = kernel32.NewProc("GetConsoleMode")
26 procSetConsoleMode = kernel32.NewProc("SetConsoleMode")
30 enableProcessedOutput = 0x0001
31 enableWrapAtEolOutput = 0x0002
32 enableVirtualTerminalProcessing = 0x0004
35 func getVersion() (float64, error) {
36 stdout, stderr := &bytes.Buffer{}, &bytes.Buffer{}
37 cmd := exec.Command("cmd", "ver")
45 // The output should be like "Microsoft Windows [Version XX.X.XXXXXX]"
46 version := strings.Replace(stdout.String(), "\n", "", -1)
47 version = strings.Replace(version, "\r\n", "", -1)
49 x1 := strings.Index(version, "[Version")
51 if x1 == -1 || strings.Index(version, "]") == -1 {
52 return -1, errors.New("Can't determine Windows version")
55 return strconv.ParseFloat(version[x1+9:x1+13], 64)
59 ver, err := getVersion()
64 // Activate Virtual Processing for Windows CMD
65 // Info: https://msdn.microsoft.com/en-us/library/windows/desktop/ms686033(v=vs.85).aspx
67 handle := syscall.Handle(os.Stderr.Fd())
68 procSetConsoleMode.Call(uintptr(handle), enableProcessedOutput|enableWrapAtEolOutput|enableVirtualTerminalProcessing)
72 // IsTerminal returns true if stderr's file descriptor is a terminal.
73 func IsTerminal(f io.Writer) bool {
74 switch v := f.(type) {
77 r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(v.Fd()), uintptr(unsafe.Pointer(&st)), 0)
78 return r != 0 && e == 0