1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798 |
- // +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"
- }
|