staros/process_win.go
starainrt d93a851d1b
feat: 完善 staros 系统能力并更新 wincmd 发布版依赖
- 重构 sysconf 为文档模型 INI Parser 与 Config Framework
- 强化 hosts 解析、插入校验、写回与异常输入处理
- 完善 StarCmd 生命周期、等待 API、流式输出与 IO 重定向
- 扩展跨平台文件时间、文件锁、内存、进程与网络能力
- 将 Windows 进程适配更新到 b612.me/wincmd v0.1.0
- 移除本地 wincmd/win32api replace,改用发布版依赖
- 将最低 Go 版本提升到 1.18
- 补充 hosts、sysconf、FileLock、StarCmd 与平台适配回归测试
2026-06-09 18:10:19 +08:00

198 lines
4.4 KiB
Go

//go:build windows
// +build windows
package staros
import (
"errors"
"fmt"
"os"
"os/exec"
"strconv"
"sync/atomic"
"time"
"b612.me/wincmd"
)
// FindProcessByName 通过进程名来查询应用信息
func FindProcessByName(pname string) (data []Process, err error) {
var lists []map[string]string
lists, err = wincmd.GetRunningProcess()
if err != nil {
return
}
for _, v := range lists {
if v["name"] == pname {
var tmp Process
tmp.Name = pname
tmp.Pid, _ = strconv.ParseInt(v["pid"], 10, 64)
tmp.PPid, _ = strconv.ParseInt(v["ppid"], 10, 64)
data = append(data, tmp)
}
}
return
}
func FindProcess(compare func(Process) bool) (data []Process, err error) {
var lists []map[string]string
lists, err = wincmd.GetRunningProcess()
if err != nil {
return
}
for _, v := range lists {
var tmp Process
tmp.Name = v["name"]
tmp.Pid, _ = strconv.ParseInt(v["pid"], 10, 64)
tmp.PPid, _ = strconv.ParseInt(v["ppid"], 10, 64)
if compare(tmp) {
data = append(data, tmp)
}
}
return
}
// FindProcessByPid 通过pid来查询应用信息
func FindProcessByPid(pid int64) (data Process, err error) {
var lists []map[string]string
lists, err = wincmd.GetRunningProcess()
if err != nil {
return
}
for _, v := range lists {
if v["pid"] == fmt.Sprint(pid) {
data.Name = v["name"]
data.Pid = pid
data.PPid, _ = strconv.ParseInt(v["ppid"], 10, 64)
return
}
}
err = errors.New("Not Found")
return
}
func Daemon(path string, args ...string) (int, error) {
cmd := exec.Command(path, args...)
if err := cmd.Start(); err != nil {
return -1, err
}
pid := cmd.Process.Pid
cmd.Process.Release()
return pid, nil
}
func DaemonWithUser(uid, gid uint32, groups []uint32, path string, args ...string) (int, error) {
return -1, ERR_UNSUPPORTED
}
func (starcli *StarCmd) SetRunUser(uid, gid uint32, groups []uint32) {
_ = starcli.SetRunUserE(uid, gid, groups)
}
func (starcli *StarCmd) SetRunUserE(uid, gid uint32, groups []uint32) error {
if starcli == nil || starcli.CMD == nil {
return errNilCommand
}
if atomic.LoadInt32(&starcli.started) != 0 {
return errCommandAlreadyStarted
}
return ERR_UNSUPPORTED
}
func (starcli *StarCmd) Release() error {
return starcli.ReleaseE()
}
func (starcli *StarCmd) Detach() error {
return starcli.DetachE()
}
func (starcli *StarCmd) ReleaseE() error {
if starcli == nil || starcli.CMD == nil {
return errNilCommand
}
if !atomic.CompareAndSwapInt32(&starcli.released, 0, 1) {
return errCommandAlreadyReleased
}
if atomic.LoadInt32(&starcli.started) != 0 {
if starcli.CMD.Process == nil {
starcli.lock.Lock()
err := starcli.runerr
starcli.lock.Unlock()
if err != nil {
atomic.StoreInt32(&starcli.released, 0)
return err
}
atomic.StoreInt32(&starcli.released, 0)
return errCommandAlreadyStarted
}
return nil
}
if err := starcli.Start(); err != nil {
atomic.StoreInt32(&starcli.released, 0)
return err
}
return nil
}
func (starcli *StarCmd) DetachE() error {
if starcli == nil || starcli.CMD == nil {
return errNilCommand
}
if !atomic.CompareAndSwapInt32(&starcli.detached, 0, 1) {
return errCommandAlreadyDetached
}
if atomic.LoadInt32(&starcli.started) != 0 {
atomic.StoreInt32(&starcli.detached, 0)
return errCommandAlreadyStarted
}
cmd := exec.Command(starcli.CMD.Path, starcli.CMD.Args[1:]...)
cmd.Dir = starcli.CMD.Dir
cmd.Env = append([]string(nil), starcli.CMD.Env...)
if starcli.CMD.SysProcAttr != nil {
attr := *starcli.CMD.SysProcAttr
cmd.SysProcAttr = &attr
}
devNull, err := os.OpenFile(os.DevNull, os.O_RDWR, 0)
if err != nil {
atomic.StoreInt32(&starcli.detached, 0)
return err
}
defer devNull.Close()
cmd.Stdin = devNull
cmd.Stdout = devNull
cmd.Stderr = devNull
if err := cmd.Start(); err != nil {
atomic.StoreInt32(&starcli.detached, 0)
return err
}
starcli.CMD.Process = cmd.Process
atomic.StoreInt32(&starcli.started, 1)
starcli.setRunning(false)
starcli.finish()
if err := cmd.Process.Release(); err != nil {
atomic.StoreInt32(&starcli.detached, 0)
return err
}
return nil
}
func (starcli *StarCmd) SetKeepCaps() error {
if starcli == nil || starcli.CMD == nil {
return errNilCommand
}
return ERR_UNSUPPORTED
}
func SetKeepCaps() error {
return ERR_UNSUPPORTED
}
func CpuUsageByPid(pid int, sleep time.Duration) float64 {
return 0
}
func Whoami() (uid, gid int, uname, gname, home string, err error) {
return 0, 0, "", "", "", ERR_UNSUPPORTED
}