Skip to content

Commit

Permalink
👔 up: sys/process - add new func: ExistsByName, StopByName
Browse files Browse the repository at this point in the history
  • Loading branch information
inhere committed Dec 3, 2024
1 parent eb4fc22 commit cd830b9
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 1 deletion.
16 changes: 15 additions & 1 deletion sysutil/process/procutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ func ProcInfo(pid int) (*os.Process, error) {
return os.FindProcess(pid)
}

// PIDByName get PID by process name match
// PIDByName get PID by process name match(by pgrep)
func PIDByName(keywords string) int {
// pgrep keywords
binFile := "pgrep"
Expand All @@ -55,3 +55,17 @@ func KillByName(keywords string, sig syscall.Signal) error {
}
return errors.New("not found process pid of " + keywords)
}

// StopProcessOption stop process option
type StopProcessOption struct {
// Check if the process exists before stopping it
CheckExist bool
// Whether to force exit the process
ForceKill bool
// Whether to wait for the process to exit
WaitExit bool
// How long to wait for the process to exit
ExitTimeout int
// Signal to send to the process(non-win)
Signal syscall.Signal
}
16 changes: 16 additions & 0 deletions sysutil/process/procutil_nonwin.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,19 @@ import "syscall"
func Kill(pid int, signal syscall.Signal) error {
return syscall.Kill(pid, signal)
}

// ExistsByName check process running by given name
func ExistsByName(name string, fuzzyMatch bool) bool {
return false // TODO
}

// StopByName Stop process based on process name.
//
// return (exists, output, error). check error to see if the process exists
//
// Usage:
//
// StopByName("MyApp.exe")
func StopByName(name string, option ...*StopProcessOption) (bool, string, error) {
return false, "", nil // TODO
}
4 changes: 4 additions & 0 deletions sysutil/process/procutil_nonwin_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
//go:build !windows
// +build !windows

package process
57 changes: 57 additions & 0 deletions sysutil/process/procutil_windows.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package process

import (
"fmt"
"strings"
"syscall"

"github.com/gookit/goutil/sysutil"
"golang.org/x/sys/windows"
)

Expand Down Expand Up @@ -41,3 +44,57 @@ func Exists(pid int) bool {
}
return true
}

// ExistsByName Determine whether a process exists based on its name(by tasklist)
//
// Usage:
//
// ExistsByName("MyApp.exe")
// // Fuzzy match by input name
// ExistsByName("MyApp", true)
func ExistsByName(name string, fuzzyMatch ...bool) bool {
// 按名称模糊匹配
if len(fuzzyMatch) > 0 && fuzzyMatch[0] {
out, err := sysutil.ShellExec("tasklist | findstr \""+name+"\" /NH", "cmd")
if err != nil {
return false
}
return strings.Contains(out, name)
}

out, err := sysutil.ExecCmd("tasklist", []string{"/FI", fmt.Sprintf("IMAGENAME eq %s", name), "/NH"})
// out, err := sysutil.ShellExec("tasklist /FI \"IMAGENAME eq "+name+"\" /NH", "cmd") // shell执行有问题
if err != nil {
return false
}
return strings.Contains(out, name)
}

// StopByName Stop process based on process name(by taskkill).
//
// return (exists, output, error). check error to see if the process exists
//
// Usage:
//
// StopByName("MyApp.exe")
func StopByName(name string, option ...*StopProcessOption) (bool, string, error) {
opt := &StopProcessOption{}
if len(option) > 0 && option[0] != nil {
opt = option[0]
}

// 1. 检查进程是否存在
if opt.CheckExist {
if !ExistsByName(name) {
return false, "", nil
}
}

// cmd: taskkill /IM name.exe /F
args := []string{"/IM", name}
if opt.ForceKill {
args = append(args, "/F")
}
out, err := sysutil.ExecCmd("taskkill", args)
return true, out, err
}
4 changes: 4 additions & 0 deletions sysutil/process/procutil_windows_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
//go:build windows
// +build windows

package process_test

0 comments on commit cd830b9

Please sign in to comment.