win32获取进程树,以及命令行参数

本文介绍如何在Windows环境下,利用Golang获取进程树及命令行参数。作者分享了一个独特的解决方法,虽然常见搜索难以找到,但经过探索最终实现并提供了示例。
摘要由CSDN通过智能技术生成

1.先上代码

package main

import (
	"bytes"
	"errors"
	"flag"
	"fmt"
	"io"
	"os"
	"sort"
	"syscall"
	"unsafe"
)

func main() {
   
	out := flag.String("o", "-", "write result to file, - eq stdout")
	flag.Parse()

	procMap := make(map[uint32]*Process, 32)
	err := ForEachProcessEntry(func(entry *syscall.ProcessEntry32) error {
   
		cmdline, err := GetCmdline(entry.ProcessID)
		if err != nil {
   
			return err
		}
		procMap[entry.ProcessID] = &Process{
   
			Pid:      entry.ProcessID,
			Ppid:     entry.ParentProcessID,
			Name:     syscall.UTF16ToString(entry.ExeFile[:]),
			Cmdline:  cmdline,
			Children: make(map[uint32]*Process),
		}
		return nil
	})
	if err != nil {
   
		fmt.Println("ForEachProcessEntry:", err)
		return
	}
	proc := make(ProcessSlice, 0, 32)
	for _, v := range procMap {
   
		if v.Pid == 0 {
   
			proc = append(proc, v)
			continue // 系统进程
		}
		tmp, ok := procMap[v.Ppid]
		if ok {
   
			tmp.Children[v.Pid] = v
		} else {
   
			proc = append(proc, v)
		}
	}
	sort.Sort(proc)

	var fmtOut *os.File
	if *out == "-" {
   
		fmtOut = os.Stdout
	} else {
   
		fmtOut, err = os.Create(*out)
		if err != nil {
   
			fmt.Println("os.Create:", *out, ",error:", err)
			return
		}
		defer fmtOut.Close()
	}

	str := bytes.NewBufferString("%10d,%10d:")
	for _, v := range proc {
   
		fmt.Fprintf(fmtOut, "%10d,%10d: name:[%s], cmdline:[%s]\n", v.Pid, v.Ppid, v.Name, v.Cmdline)
		WriteChildren(fmtOut, v.Children, str, 1)
	}
}

func WriteChildren(w io.Writer, children map[uint32]*Process, strFmt *bytes.Buffer, layer int) {
   
	if len(children) == 0 {
   
		return
	}
	strFmt.Truncate(10 /* len("%10d,%10d:") */)
	for i := 0; i < layer*4; i++ {
   
		if i > 0 && i%4 == 0 {
   
			strFmt.WriteByte('|')
		}
		strFmt.WriteByte(' ')
	}
	strFmt.WriteString("\\_ name:[%s], cmdline:[%s]\n")
	fmtStr := strFmt.String()
	layer++
	for _, v := range children {
   
		fmt.Fprintf(w, fmtStr, v.Pid, v.Ppid, v.Name, v.Cmdline)
		WriteChildren(w, v.Children, strFmt, layer) // 递归打印子进程
	}
}

type (
	Process struct {
   
		Pid, Ppid uint32
		Name      string
		Cmdline   string
		Children  map[uint32]*Process
	}
	ProcessSlice []*Process
)

func (d ProcessSlice) Less(i, j int) bool {
   
	return d[i].Pid < d[j].Pid
}

func (d ProcessSlice) Swap(i, j int) {
   
	d[i], d[j] = d[j], d[i]
}

func (d ProcessSlice) 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值