gitee.com/h79/goutils@v1.22.10/common/system/process_windows.go (about)

     1  package system
     2  
     3  import (
     4  	"fmt"
     5  	"golang.org/x/sys/windows"
     6  	"path/filepath"
     7  	"syscall"
     8  	"unsafe"
     9  )
    10  
    11  type windowsProcess struct {
    12  	pid  int32
    13  	ppid int32
    14  	exe  string
    15  	path string
    16  }
    17  
    18  func (p *windowsProcess) Pid() int32 {
    19  	return p.pid
    20  }
    21  
    22  func (p *windowsProcess) PPid() int32 {
    23  	return p.ppid
    24  }
    25  
    26  func (p *windowsProcess) Name() string {
    27  	return p.exe
    28  }
    29  
    30  func (p *windowsProcess) Path() string {
    31  	return p.path
    32  }
    33  
    34  func getProcessPath(pid int32, name string) (string, error) {
    35  	snap, err := windows.CreateToolhelp32Snapshot(windows.TH32CS_SNAPMODULE, uint32(pid))
    36  	if err != nil {
    37  		return "", err
    38  	}
    39  	defer windows.CloseHandle(snap)
    40  	var pe32 windows.ModuleEntry32
    41  	pe32.Size = uint32(unsafe.Sizeof(pe32))
    42  	if err = windows.Module32First(snap, &pe32); err != nil {
    43  		return "", err
    44  	}
    45  	for {
    46  		module := windows.UTF16ToString(pe32.Module[:])
    47  		if pe32.ProcessID == uint32(pid) && module == name {
    48  			path := windows.UTF16ToString(pe32.ExePath[:])
    49  			return filepath.Dir(path), nil
    50  		}
    51  		if err = windows.Module32Next(snap, &pe32); err != nil {
    52  			break
    53  		}
    54  	}
    55  	return "", fmt.Errorf("couldn't find pid: %d", pid)
    56  }
    57  
    58  func newProcessFromEntry(entry *windows.ProcessEntry32) Process {
    59  	if entry == nil {
    60  		return nil
    61  	}
    62  	na := getProcessName(entry)
    63  	pa, _ := getProcessPath(int32(entry.ProcessID), na)
    64  	return &windowsProcess{path: pa, exe: na, pid: int32(entry.ProcessID), ppid: int32(entry.ParentProcessID)}
    65  }
    66  
    67  func getProcessName(entry *windows.ProcessEntry32) string {
    68  	return syscall.UTF16ToString(entry.ExeFile[:])
    69  }
    70  
    71  func newProcessEntry() *windows.ProcessEntry32 {
    72  	var entry windows.ProcessEntry32
    73  	entry.Size = uint32(unsafe.Sizeof(entry))
    74  	return &entry
    75  }
    76  
    77  func getProcesses() ([]Process, error) {
    78  	const snapProcess = 0x00000002
    79  	handle, err := windows.CreateToolhelp32Snapshot(snapProcess, 0)
    80  	if err != nil {
    81  		return nil, err
    82  	}
    83  	defer windows.CloseHandle(handle)
    84  
    85  	entry := newProcessEntry()
    86  	// take first process
    87  	err = windows.Process32First(handle, entry)
    88  	if err != nil {
    89  		return nil, err
    90  	}
    91  	results := make([]Process, 0, 50)
    92  	for {
    93  		if entry.ProcessID > 0 {
    94  			results = append(results, newProcessFromEntry(entry))
    95  		}
    96  		if err = windows.Process32Next(handle, entry); err != nil {
    97  			// catch syscall.ERROR_NO_MORE_FILES on the end of process list
    98  			if err == syscall.ERROR_NO_MORE_FILES {
    99  				break
   100  			}
   101  			return nil, err
   102  		}
   103  	}
   104  	return results, nil
   105  }