Go 如何通过进程名获取进程id?

Go 如何通过进程名获取进程id?,go,Go,我想在windows环境中通过进程名称获取进程id 我发现golang只有apios.FindProcess(id),但没有名称。您可以列出所有进程,并使用更新的sys call包将它们与您想要查找的名称进行匹配, 它拥有大部分windows api func Process32First(snapshot Handle, procEntry *ProcessEntry32) (err error) func Process32Next(snapshot Handle, procEntry *P

我想在windows环境中通过进程名称获取进程id


我发现golang只有api
os.FindProcess(id)
,但没有名称。

您可以列出所有进程,并使用更新的sys call包将它们与您想要查找的名称进行匹配, 它拥有大部分windows api

func Process32First(snapshot Handle, procEntry *ProcessEntry32) (err error)
func Process32Next(snapshot Handle, procEntry *ProcessEntry32) (err error)
另请参见msdn文档:

我也不得不与之斗争,并发现解决方案的方法不是很简单,因为……WinApi:)

最后,您必须使用
CreateToolhelp32Snapshot
创建当前windows进程列表的快照。然后使用
Process32First
获得快照中的第一个进程。之后,继续使用
Process32Next
在列表上迭代,直到出现
错误\u无更多\u文件
错误。只有这样,您才有完整的流程列表

有关工作示例,请参见

要点如下:

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]),
    }
}
这似乎可以做到:

package main

import (
   "fmt"
   "golang.org/x/sys/windows"
)

// unsafe.Sizeof(windows.ProcessEntry32{})
const processEntrySize = 568

func processID(name string) (uint32, error) {
   h, e := windows.CreateToolhelp32Snapshot(windows.TH32CS_SNAPPROCESS, 0)
   if e != nil { return 0, e }
   p := windows.ProcessEntry32{Size: processEntrySize}
   for {
      e := windows.Process32Next(h, &p)
      if e != nil { return 0, e }
      if windows.UTF16ToString(p.ExeFile[:]) == name {
         return p.ProcessID, nil
      }
   }
   return 0, fmt.Errorf("%q not found", name)
}

func main() {
   n, e := processID("WindowsTerminal.exe")
   if e != nil {
      panic(e)
   }
   println(n)
}

您可以在golang程序中执行“tasklist.exe”,并在golang中处理输出以查找进程名称。
package main

import (
   "fmt"
   "golang.org/x/sys/windows"
)

// unsafe.Sizeof(windows.ProcessEntry32{})
const processEntrySize = 568

func processID(name string) (uint32, error) {
   h, e := windows.CreateToolhelp32Snapshot(windows.TH32CS_SNAPPROCESS, 0)
   if e != nil { return 0, e }
   p := windows.ProcessEntry32{Size: processEntrySize}
   for {
      e := windows.Process32Next(h, &p)
      if e != nil { return 0, e }
      if windows.UTF16ToString(p.ExeFile[:]) == name {
         return p.ProcessID, nil
      }
   }
   return 0, fmt.Errorf("%q not found", name)
}

func main() {
   n, e := processID("WindowsTerminal.exe")
   if e != nil {
      panic(e)
   }
   println(n)
}