如何以内存安全的方式获取前台应用程序的 pid?

我想获得前台应用程序的 pid。请不要推荐robotgo,我已经尝试过并且知道它可以工作,但是正如我对问题的评论那样会导致内存泄漏。就像那里提到的代码一样,我想在循环中获取一个 pid,所以它应该是内存安全的。



largeQ
浏览 188回答 2
2回答

杨魅力

如果我正确理解您的问题,我认为以下程序应该会有所帮助。我正在使用该mitchellh/go-ps软件包。package mainimport (&nbsp; &nbsp; "flag"&nbsp; &nbsp; "fmt"&nbsp; &nbsp; "os"&nbsp; &nbsp; "os/exec"&nbsp; &nbsp; "strconv"&nbsp; &nbsp; "strings"&nbsp; &nbsp; "time"&nbsp; &nbsp; ps "github.com/mitchellh/go-ps")func foreground(pid int) (bool, error) {&nbsp; &nbsp; out, err := exec.Command("/bin/ps", "-o", "stat=", "-p", strconv.Itoa(int(pid))).Output()&nbsp; &nbsp; if err != nil {&nbsp; &nbsp; &nbsp; &nbsp; return false, err&nbsp; &nbsp; }&nbsp; &nbsp; return strings.IndexByte(string(out), '+') != -1, nil}func getProcs() error {&nbsp; &nbsp; procs, err := ps.Processes()&nbsp; &nbsp; if err != nil {&nbsp; &nbsp; &nbsp; &nbsp; return err&nbsp; &nbsp; }&nbsp; &nbsp; for _, p := range procs {&nbsp; &nbsp; &nbsp; &nbsp; ok, err := foreground(p.Pid())&nbsp; &nbsp; &nbsp; &nbsp; if err != nil {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fmt.Fprintf(os.Stderr, "error: %v\n", err)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; continue&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; if ok {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fmt.Fprintf(os.Stdout, "pid: %d, process: %s\n", p.Pid(), p.Executable())&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; return nil}func scheduler(tick chan<- struct{}, every time.Duration) {&nbsp; &nbsp; tick <- struct{}{}&nbsp; &nbsp; for range time.Tick(every * time.Second) {&nbsp; &nbsp; &nbsp; &nbsp; tick <- struct{}{}&nbsp; &nbsp; }}func main() {&nbsp; &nbsp; dur := flag.Duration("every", 10, "interval (in seconds)")&nbsp; &nbsp; flag.Parse()&nbsp; &nbsp; if *dur <= 0 {&nbsp; &nbsp; &nbsp; &nbsp; fmt.Fprintf(os.Stderr, "interval should be more than 0")&nbsp; &nbsp; &nbsp; &nbsp; os.Exit(1)&nbsp; &nbsp; }&nbsp; &nbsp; tick := make(chan struct{})&nbsp; &nbsp; go scheduler(tick, *dur)&nbsp; &nbsp; for range tick {&nbsp; &nbsp; &nbsp; &nbsp; if err := getProcs(); err != nil {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fmt.Fprintf(os.Stderr, "error: %v\n", err)&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}更新:我已经更新了答案。现在您可以打印在前台运行的进程。由于基于 darwin 的操作系统中 procfs 不可用,我们依赖于ps. 因此,如果进程在前台运行,使用ps -o stat= -p $PID会给我们一个信号。+因此,前台进程背后的理论是process's group id == controlling tty process's group id.

江户川乱折腾

package mainimport (&nbsp; &nbsp; "flag"&nbsp; &nbsp; "fmt"&nbsp; &nbsp; "os"&nbsp; &nbsp; "time"&nbsp; &nbsp; ps "github.com/shirou/gopsutil/process")func getProcs() error {&nbsp; &nbsp; procs, err := ps.Processes()&nbsp; &nbsp; if err != nil {&nbsp; &nbsp; &nbsp; &nbsp; return err&nbsp; &nbsp; }&nbsp; &nbsp; for _, p := range procs {&nbsp; &nbsp; &nbsp; &nbsp; name, _ := p.Name()&nbsp; &nbsp; &nbsp; &nbsp; foreground, _ := p.Foreground()&nbsp; &nbsp; &nbsp; &nbsp; fmt.Fprintf(os.Stdout, "pid: %d,\tprocess: %s ,\tForeground: %v\n", p.Pid, name, foreground)&nbsp; &nbsp; }&nbsp; &nbsp; return nil}func main() {&nbsp; &nbsp; for range time.Tick(1 * time.Second) {&nbsp; &nbsp; &nbsp; &nbsp; if err := getProcs(); err != nil {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fmt.Fprintf(os.Stderr, "error: %v\n", err)&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}它基于 shmsr 的回答,但不同的库为进程提供更多信息
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go