gitee.com/h79/goutils@v1.22.10/common/system/process_windows.go (about) 1 package system 2 3 import ( 4 "fmt" 5 "golang.org/x/sys/windows" 6 "path/filepath" 7 "syscall" 8 "unsafe" 9 ) 10 11 type windowsProcess struct { 12 pid int32 13 ppid int32 14 exe string 15 path string 16 } 17 18 func (p *windowsProcess) Pid() int32 { 19 return p.pid 20 } 21 22 func (p *windowsProcess) PPid() int32 { 23 return p.ppid 24 } 25 26 func (p *windowsProcess) Name() string { 27 return p.exe 28 } 29 30 func (p *windowsProcess) Path() string { 31 return p.path 32 } 33 34 func getProcessPath(pid int32, name string) (string, error) { 35 snap, err := windows.CreateToolhelp32Snapshot(windows.TH32CS_SNAPMODULE, uint32(pid)) 36 if err != nil { 37 return "", err 38 } 39 defer windows.CloseHandle(snap) 40 var pe32 windows.ModuleEntry32 41 pe32.Size = uint32(unsafe.Sizeof(pe32)) 42 if err = windows.Module32First(snap, &pe32); err != nil { 43 return "", err 44 } 45 for { 46 module := windows.UTF16ToString(pe32.Module[:]) 47 if pe32.ProcessID == uint32(pid) && module == name { 48 path := windows.UTF16ToString(pe32.ExePath[:]) 49 return filepath.Dir(path), nil 50 } 51 if err = windows.Module32Next(snap, &pe32); err != nil { 52 break 53 } 54 } 55 return "", fmt.Errorf("couldn't find pid: %d", pid) 56 } 57 58 func newProcessFromEntry(entry *windows.ProcessEntry32) Process { 59 if entry == nil { 60 return nil 61 } 62 na := getProcessName(entry) 63 pa, _ := getProcessPath(int32(entry.ProcessID), na) 64 return &windowsProcess{path: pa, exe: na, pid: int32(entry.ProcessID), ppid: int32(entry.ParentProcessID)} 65 } 66 67 func getProcessName(entry *windows.ProcessEntry32) string { 68 return syscall.UTF16ToString(entry.ExeFile[:]) 69 } 70 71 func newProcessEntry() *windows.ProcessEntry32 { 72 var entry windows.ProcessEntry32 73 entry.Size = uint32(unsafe.Sizeof(entry)) 74 return &entry 75 } 76 77 func getProcesses() ([]Process, error) { 78 const snapProcess = 0x00000002 79 handle, err := windows.CreateToolhelp32Snapshot(snapProcess, 0) 80 if err != nil { 81 return nil, err 82 } 83 defer windows.CloseHandle(handle) 84 85 entry := newProcessEntry() 86 // take first process 87 err = windows.Process32First(handle, entry) 88 if err != nil { 89 return nil, err 90 } 91 results := make([]Process, 0, 50) 92 for { 93 if entry.ProcessID > 0 { 94 results = append(results, newProcessFromEntry(entry)) 95 } 96 if err = windows.Process32Next(handle, entry); err != nil { 97 // catch syscall.ERROR_NO_MORE_FILES on the end of process list 98 if err == syscall.ERROR_NO_MORE_FILES { 99 break 100 } 101 return nil, err 102 } 103 } 104 return results, nil 105 }