I also had to struggle with this, and finding a way to a solution is not very simple, because ... WinApi :)
In the end, you should create a snapshot of the current list of Windows processes using CreateToolhelp32Snapshot . Then you get the first process in the snapshot with Process32First . After that, continue to Process32Next over the list with Process32Next until you get the error ERROR_NO_MORE_FILES . Only then do you have an entire list of processes.
See how2readwindowsprocesses for a working example.
Here is the gist:
const TH32CS_SNAPPROCESS = 0x00000002 type WindowsProcess struct { ProcessID int ParentProcessID int Exe string } func processes() ([]WindowsProcess, error) { handle, err := windows.CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0) if err != nil { return nil, err } defer windows.CloseHandle(handle) var entry windows.ProcessEntry32 entry.Size = uint32(unsafe.Sizeof(entry)) // get the first process err = windows.Process32First(handle, &entry) if err != nil { return nil, err } results := make([]WindowsProcess, 0, 50) for { results = append(results, newWindowsProcess(&entry)) err = windows.Process32Next(handle, &entry) if err != nil { // windows sends ERROR_NO_MORE_FILES on last process if err == syscall.ERROR_NO_MORE_FILES { return results, nil } return nil, err } } } func findProcessByName(processes []WindowsProcess, name string) *WindowsProcess { for _, p := range processes { if strings.ToLower(p.Exe) == strings.ToLower(name) { return &p } } return nil } func newWindowsProcess(e *windows.ProcessEntry32) WindowsProcess { // Find when the string ends for decoding end := 0 for { if e.ExeFile[end] == 0 { break } end++ } return WindowsProcess{ ProcessID: int(e.ProcessID), ParentProcessID: int(e.ParentProcessID), Exe: syscall.UTF16ToString(e.ExeFile[:end]), } }
source share