12 func getProcessEntry(pid int) (*syscall.ProcessEntry32, error) {
13 snapshot, err := syscall.CreateToolhelp32Snapshot(syscall.TH32CS_SNAPPROCESS, 0)
17 defer syscall.CloseHandle(snapshot)
18 var procEntry syscall.ProcessEntry32
19 procEntry.Size = uint32(unsafe.Sizeof(procEntry))
20 if err = syscall.Process32First(snapshot, &procEntry); err != nil {
24 if procEntry.ProcessID == uint32(pid) {
25 return &procEntry, nil
27 err = syscall.Process32Next(snapshot, &procEntry)
34 // StartedByExplorer returns true if the program was invoked by the user double-clicking
35 // on the executable from explorer.exe
37 // It is conservative and returns false if any of the internal calls fail.
38 // It does not guarantee that the program was run from a terminal. It only can tell you
39 // whether it was launched from explorer.exe
40 func StartedByExplorer() bool {
41 pe, err := getProcessEntry(os.Getppid())
45 return "explorer.exe" == syscall.UTF16ToString(pe.ExeFile[:])