12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182 |
- // Based on ssh/terminal:
- // Copyright 2011 The Go Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style
- // license that can be found in the LICENSE file.
- // +build windows,!appengine
- package logrus
- import (
- "bytes"
- "errors"
- "io"
- "os"
- "os/exec"
- "strconv"
- "strings"
- "syscall"
- "unsafe"
- )
- var kernel32 = syscall.NewLazyDLL("kernel32.dll")
- var (
- procGetConsoleMode = kernel32.NewProc("GetConsoleMode")
- procSetConsoleMode = kernel32.NewProc("SetConsoleMode")
- )
- const (
- enableProcessedOutput = 0x0001
- enableWrapAtEolOutput = 0x0002
- enableVirtualTerminalProcessing = 0x0004
- )
- func getVersion() (float64, error) {
- stdout, stderr := &bytes.Buffer{}, &bytes.Buffer{}
- cmd := exec.Command("cmd", "ver")
- cmd.Stdout = stdout
- cmd.Stderr = stderr
- err := cmd.Run()
- if err != nil {
- return -1, err
- }
- // The output should be like "Microsoft Windows [Version XX.X.XXXXXX]"
- version := strings.Replace(stdout.String(), "\n", "", -1)
- version = strings.Replace(version, "\r\n", "", -1)
- x1 := strings.Index(version, "[Version")
- if x1 == -1 || strings.Index(version, "]") == -1 {
- return -1, errors.New("Can't determine Windows version")
- }
- return strconv.ParseFloat(version[x1+9:x1+13], 64)
- }
- func init() {
- ver, err := getVersion()
- if err != nil {
- return
- }
- // Activate Virtual Processing for Windows CMD
- // Info: https://msdn.microsoft.com/en-us/library/windows/desktop/ms686033(v=vs.85).aspx
- if ver >= 10 {
- handle := syscall.Handle(os.Stderr.Fd())
- procSetConsoleMode.Call(uintptr(handle), enableProcessedOutput|enableWrapAtEolOutput|enableVirtualTerminalProcessing)
- }
- }
- // IsTerminal returns true if stderr's file descriptor is a terminal.
- func IsTerminal(f io.Writer) bool {
- switch v := f.(type) {
- case *os.File:
- var st uint32
- r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(v.Fd()), uintptr(unsafe.Pointer(&st)), 0)
- return r != 0 && e == 0
- default:
- return false
- }
- }
|