text: // +build windows
  // +build !go1.4
  
  package mousetrap
  
  import (
  	"fmt"
  	"os"
  	"syscall"
  	"unsafe"
  )
  
  const (
  	// defined by the Win32 API
  	th32cs_snapprocess uintptr = 0x2
  )
  
  var (
  	kernel                   = syscall.MustLoadDLL("kernel32.dll")
  	CreateToolhelp32Snapshot = kernel.MustFindProc("CreateToolhelp32Snapshot")
  	Process32First           = kernel.MustFindProc("Process32FirstW")
  	Process32Next            = kernel.MustFindProc("Process32NextW")
  )
  
  // ProcessEntry32 structure defined by the Win32 API
  type processEntry32 struct {
  	dwSize              uint32
  	cntUsage            uint32
  	th32ProcessID       uint32
  	th32DefaultHeapID   int
  	th32ModuleID        uint32
  	cntThreads          uint32
  	th32ParentProcessID uint32
  	pcPriClassBase      int32
  	dwFlags             uint32
  	szExeFile           [syscall.MAX_PATH]uint16
  }
  
  func getProcessEntry(pid int) (pe *processEntry32, err error) {
  	snapshot, _, e1 := CreateToolhelp32Snapshot.Call(th32cs_snapprocess, uintptr(0))
  	if snapshot == uintptr(syscall.InvalidHandle) {
  		err = fmt.Errorf("CreateToolhelp32Snapshot: %v", e1)
  		return
  	}
  	defer syscall.CloseHandle(syscall.Handle(snapshot))
  
  	var processEntry processEntry32
  	processEntry.dwSize = uint32(unsafe.Sizeof(processEntry))
  	ok, _, e1 := Process32First.Call(snapshot, uintptr(unsafe.Pointer(&processEntry)))
  	if ok == 0 {
  		err = fmt.Errorf("Process32First: %v", e1)
  		return
  	}
  
  	for {
  		if processEntry.th32ProcessID == uint32(pid) {
  			pe = &processEntry
  			return
  		}
  
  		ok, _, e1 = Process32Next.Call(snapshot, uintptr(unsafe.Pointer(&processEntry)))
  		if ok == 0 {
  			err = fmt.Errorf("Process32Next: %v", e1)
  			return
  		}
  	}
  }
  
  func getppid() (pid int, err error) {
  	pe, err := getProcessEntry(os.Getpid())
  	if err != nil {
  		return
  	}
  
  	pid = int(pe.th32ParentProcessID)
  	return
  }
  
  // StartedByExplorer returns true if the program was invoked by the user double-clicking
  // on the executable from explorer.exe
  //
  // It is conservative and returns false if any of the internal calls fail.
  // It does not guarantee that the program was run from a terminal. It only can tell you
  // whether it was launched from explorer.exe
  func StartedByExplorer() bool {
  	ppid, err := getppid()
  	if err != nil {
  		return false
  	}
  
  	pe, err := getProcessEntry(ppid)
  	if err != nil {
  		return false
  	}
  
  	name := syscall.UTF16ToString(pe.szExeFile[:])
  	return name == "explorer.exe"
  }
  