How to get process id by process name in windows environment?

huangapple go评论128阅读模式
英文:

How to get process id by process name in windows environment?

问题

我想在Windows环境中通过进程名称获取进程ID。我发现Golang只有os.FindProcess(id)这个API,没有按名称查找的方法。

英文:

I want to get the process id by the process name in windows environment?

I find golang only has the api os.FindProcess(id),but no by name.

答案1

得分: 5

我也曾经遇到这个问题,并且发现解决方案并不是很直接,因为涉及到了 WinApi How to get process id by process name in windows environment?

最终,你需要使用CreateToolhelp32Snapshot函数创建当前窗口进程列表的快照。然后,使用Process32First函数获取快照中的第一个进程。之后,使用Process32Next函数迭代列表,直到出现ERROR_NO_MORE_FILES错误。只有在这时,你才拥有完整的进程列表。

可以参考how2readwindowsprocesses中的示例代码。

以下是代码示例:

  1. const TH32CS_SNAPPROCESS = 0x00000002
  2. type WindowsProcess struct {
  3. ProcessID int
  4. ParentProcessID int
  5. Exe string
  6. }
  7. func processes() ([]WindowsProcess, error) {
  8. handle, err := windows.CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
  9. if err != nil {
  10. return nil, err
  11. }
  12. defer windows.CloseHandle(handle)
  13. var entry windows.ProcessEntry32
  14. entry.Size = uint32(unsafe.Sizeof(entry))
  15. // 获取第一个进程
  16. err = windows.Process32First(handle, &entry)
  17. if err != nil {
  18. return nil, err
  19. }
  20. results := make([]WindowsProcess, 0, 50)
  21. for {
  22. results = append(results, newWindowsProcess(&entry))
  23. err = windows.Process32Next(handle, &entry)
  24. if err != nil {
  25. // 最后一个进程时,Windows 会返回 ERROR_NO_MORE_FILES
  26. if err == syscall.ERROR_NO_MORE_FILES {
  27. return results, nil
  28. }
  29. return nil, err
  30. }
  31. }
  32. }
  33. func findProcessByName(processes []WindowsProcess, name string) *WindowsProcess {
  34. for _, p := range processes {
  35. if strings.ToLower(p.Exe) == strings.ToLower(name) {
  36. return &p
  37. }
  38. }
  39. return nil
  40. }
  41. func newWindowsProcess(e *windows.ProcessEntry32) WindowsProcess {
  42. // 找到字符串结束的位置以进行解码
  43. end := 0
  44. for {
  45. if e.ExeFile[end] == 0 {
  46. break
  47. }
  48. end++
  49. }
  50. return WindowsProcess{
  51. ProcessID: int(e.ProcessID),
  52. ParentProcessID: int(e.ParentProcessID),
  53. Exe: syscall.UTF16ToString(e.ExeFile[:end]),
  54. }
  55. }
英文:

I had to struggle with this too, and found the way to the solution not very straightforward, because… WinApi How to get process id by process name in windows environment?

In the end you have to create a snapshot of the current windows process list using CreateToolhelp32Snapshot. Then you get the first process in the snapshot with Process32First. After that keep iterating over the list with Process32Next, until you get the ERROR_NO_MORE_FILES error. Only then you have the whole process list.

See how2readwindowsprocesses for a working example.

Here is the gist:

  1. const TH32CS_SNAPPROCESS = 0x00000002
  2. type WindowsProcess struct {
  3. ProcessID int
  4. ParentProcessID int
  5. Exe string
  6. }
  7. func processes() ([]WindowsProcess, error) {
  8. handle, err := windows.CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
  9. if err != nil {
  10. return nil, err
  11. }
  12. defer windows.CloseHandle(handle)
  13. var entry windows.ProcessEntry32
  14. entry.Size = uint32(unsafe.Sizeof(entry))
  15. // get the first process
  16. err = windows.Process32First(handle, &entry)
  17. if err != nil {
  18. return nil, err
  19. }
  20. results := make([]WindowsProcess, 0, 50)
  21. for {
  22. results = append(results, newWindowsProcess(&entry))
  23. err = windows.Process32Next(handle, &entry)
  24. if err != nil {
  25. // windows sends ERROR_NO_MORE_FILES on last process
  26. if err == syscall.ERROR_NO_MORE_FILES {
  27. return results, nil
  28. }
  29. return nil, err
  30. }
  31. }
  32. }
  33. func findProcessByName(processes []WindowsProcess, name string) *WindowsProcess {
  34. for _, p := range processes {
  35. if strings.ToLower(p.Exe) == strings.ToLower(name) {
  36. return &p
  37. }
  38. }
  39. return nil
  40. }
  41. func newWindowsProcess(e *windows.ProcessEntry32) WindowsProcess {
  42. // Find when the string ends for decoding
  43. end := 0
  44. for {
  45. if e.ExeFile[end] == 0 {
  46. break
  47. }
  48. end++
  49. }
  50. return WindowsProcess{
  51. ProcessID: int(e.ProcessID),
  52. ParentProcessID: int(e.ParentProcessID),
  53. Exe: syscall.UTF16ToString(e.ExeFile[:end]),
  54. }
  55. }

答案2

得分: 2

你可以使用更新的sys调用包(https://godoc.org/golang.org/x/sys)列出所有进程,并将它们与你想要查找的名称进行匹配,该包包含了大部分Windows API。

以下是相关的函数:

  1. func Process32First(snapshot Handle, procEntry *ProcessEntry32) (err error)
  2. func Process32Next(snapshot Handle, procEntry *ProcessEntry32) (err error)

你还可以参考MSDN文档(https://msdn.microsoft.com/en-us/library/windows/desktop/ms684834(v=vs.85).aspx)。

英文:

You can list all the processes and match them with the name you want to find, by using the updated sys call package, https://godoc.org/golang.org/x/sys,
it has most of the windows api.

  1. func Process32First(snapshot Handle, procEntry *ProcessEntry32) (err error)
  2. func Process32Next(snapshot Handle, procEntry *ProcessEntry32) (err error)

also see the msdn docs:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms684834(v=vs.85).aspx

答案3

得分: 2

这似乎可以实现:

  1. package main
  2. import (
  3. "fmt"
  4. "golang.org/x/sys/windows"
  5. )
  6. // unsafe.Sizeof(windows.ProcessEntry32{})
  7. const processEntrySize = 568
  8. func processID(name string) (uint32, error) {
  9. h, e := windows.CreateToolhelp32Snapshot(windows.TH32CS_SNAPPROCESS, 0)
  10. if e != nil { return 0, e }
  11. p := windows.ProcessEntry32{Size: processEntrySize}
  12. for {
  13. e := windows.Process32Next(h, &p)
  14. if e != nil { return 0, e }
  15. if windows.UTF16ToString(p.ExeFile[:]) == name {
  16. return p.ProcessID, nil
  17. }
  18. }
  19. return 0, fmt.Errorf("%q not found", name)
  20. }
  21. func main() {
  22. n, e := processID("WindowsTerminal.exe")
  23. if e != nil {
  24. panic(e)
  25. }
  26. println(n)
  27. }

https://pkg.go.dev/golang.org/x/sys/windows#CreateToolhelp32Snapshot

英文:

This seems to do it:

  1. package main
  2. import (
  3. "fmt"
  4. "golang.org/x/sys/windows"
  5. )
  6. // unsafe.Sizeof(windows.ProcessEntry32{})
  7. const processEntrySize = 568
  8. func processID(name string) (uint32, error) {
  9. h, e := windows.CreateToolhelp32Snapshot(windows.TH32CS_SNAPPROCESS, 0)
  10. if e != nil { return 0, e }
  11. p := windows.ProcessEntry32{Size: processEntrySize}
  12. for {
  13. e := windows.Process32Next(h, &p)
  14. if e != nil { return 0, e }
  15. if windows.UTF16ToString(p.ExeFile[:]) == name {
  16. return p.ProcessID, nil
  17. }
  18. }
  19. return 0, fmt.Errorf("%q not found", name)
  20. }
  21. func main() {
  22. n, e := processID("WindowsTerminal.exe")
  23. if e != nil {
  24. panic(e)
  25. }
  26. println(n)
  27. }

https://pkg.go.dev/golang.org/x/sys/windows#CreateToolhelp32Snapshot

答案4

得分: 1

  1. const TH32CS_SNAPPROCESS = 0x00000002
  2. type WindowsProcess struct {
  3. ProcessID int
  4. ParentProcessID int
  5. Exe string
  6. }
  7. func newWindowsProcess(e *syscall.ProcessEntry32) WindowsProcess {
  8. // Find when the string ends for decoding
  9. end := 0
  10. for {
  11. if e.ExeFile[end] == 0 {
  12. break
  13. }
  14. end++
  15. }
  16. return WindowsProcess{
  17. ProcessID: int(e.ProcessID),
  18. ParentProcessID: int(e.ParentProcessID),
  19. Exe: syscall.UTF16ToString(e.ExeFile[:end]),
  20. }
  21. }
  22. func processes() ([]WindowsProcess, error) {
  23. handle, err := syscall.CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
  24. if err != nil {
  25. return nil, err
  26. }
  27. defer syscall.CloseHandle(handle)
  28. var entry syscall.ProcessEntry32
  29. entry.Size = uint32(unsafe.Sizeof(entry))
  30. // get the first process
  31. err = syscall.Process32First(handle, &entry)
  32. if err != nil {
  33. return nil, err
  34. }
  35. results := make([]WindowsProcess, 0, 50)
  36. for {
  37. results = append(results, newWindowsProcess(&entry))
  38. err = syscall.Process32Next(handle, &entry)
  39. if err != nil {
  40. // windows sends ERROR_NO_MORE_FILES on last process
  41. if err == syscall.ERROR_NO_MORE_FILES {
  42. return results, nil
  43. }
  44. return nil, err
  45. }
  46. }
  47. }
  48. func findProcessByName(processes []WindowsProcess, name string) *WindowsProcess {
  49. for _, p := range processes {
  50. if bytes.Contains([]byte(strings.ToUpper(p.Exe)), []byte(strings.ToUpper(name))) {
  51. return &p
  52. }
  53. }
  54. return nil
  55. }
英文:
  1. const TH32CS_SNAPPROCESS = 0x00000002
  2. type WindowsProcess struct {
  3. ProcessID int
  4. ParentProcessID int
  5. Exe string
  6. }
  7. func newWindowsProcess(e *syscall.ProcessEntry32) WindowsProcess {
  8. // Find when the string ends for decoding
  9. end := 0
  10. for {
  11. if e.ExeFile[end] == 0 {
  12. break
  13. }
  14. end++
  15. }
  16. return WindowsProcess{
  17. ProcessID: int(e.ProcessID),
  18. ParentProcessID: int(e.ParentProcessID),
  19. Exe: syscall.UTF16ToString(e.ExeFile[:end]),
  20. }
  21. }
  22. func processes() ([]WindowsProcess, error) {
  23. handle, err := syscall.CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
  24. if err != nil {
  25. return nil, err
  26. }
  27. defer syscall.CloseHandle(handle)
  28. var entry syscall.ProcessEntry32
  29. entry.Size = uint32(unsafe.Sizeof(entry))
  30. // get the first process
  31. err = syscall.Process32First(handle, &entry)
  32. if err != nil {
  33. return nil, err
  34. }
  35. results := make([]WindowsProcess, 0, 50)
  36. for {
  37. results = append(results, newWindowsProcess(&entry))
  38. err = syscall.Process32Next(handle, &entry)
  39. if err != nil {
  40. // windows sends ERROR_NO_MORE_FILES on last process
  41. if err == syscall.ERROR_NO_MORE_FILES {
  42. return results, nil
  43. }
  44. return nil, err
  45. }
  46. }
  47. }
  48. func findProcessByName(processes []WindowsProcess, name string) *WindowsProcess {
  49. for _, p := range processes {
  50. if bytes.Contains([]byte(strings.ToUpper(p.Exe)), []byte(strings.ToUpper(name))) {
  51. return &p
  52. }
  53. }
  54. return nil
  55. }

huangapple
  • 本文由 发表于 2016年3月31日 20:45:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/36333896.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定