Den*_*eck 5

我也不得不为此苦苦挣扎,并且发现解决方案的方法不是很简单,因为…… WinApi :)

CreateToolhelp32SnapshotProcess32FirstProcess32NextERROR_NO_MORE_FILES

有关工作示例,请参阅how2readwindowsprocesses 。

这是要点:

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]),
    }
}