+ 实现基础 web 服务,提供 /ping、/list、/stop 路由
This commit is contained in:
39
src/main.go
Normal file
39
src/main.go
Normal file
@@ -0,0 +1,39 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
||||
// p := listProcess("kugou")
|
||||
// for _, ps := range p {
|
||||
// fmt.Println(ps.Pid, ps.Name)
|
||||
// }
|
||||
|
||||
s := Service{
|
||||
Port: 12340,
|
||||
}
|
||||
s.Run()
|
||||
}
|
||||
|
||||
// 获取本机 IP 地址
|
||||
func GetLocalIP() []string {
|
||||
addrs, err := net.InterfaceAddrs()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
ip := []string{}
|
||||
for _, address := range addrs {
|
||||
// 检查ip地址判断是否回环地址
|
||||
if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
|
||||
if ipnet.IP.To4() != nil {
|
||||
ip = append(ip, ipnet.IP.String())
|
||||
}
|
||||
}
|
||||
}
|
||||
return ip
|
||||
}
|
||||
34
src/main.http
Normal file
34
src/main.http
Normal file
@@ -0,0 +1,34 @@
|
||||
@url=http://localhost:12340
|
||||
@accept=Accept: application/json
|
||||
@content-type=Content-Type: application/json
|
||||
|
||||
|
||||
###
|
||||
GET {{url}}/ping
|
||||
{{accept}}
|
||||
|
||||
###
|
||||
GET {{url}}/list
|
||||
{{accept}}
|
||||
|
||||
###
|
||||
GET {{url}}/list?name=notepad
|
||||
{{accept}}
|
||||
|
||||
###
|
||||
GET {{url}}/listps
|
||||
{{accept}}
|
||||
|
||||
###
|
||||
GET {{url}}/listps?name=Notepad
|
||||
{{accept}}
|
||||
|
||||
###
|
||||
POST {{url}}/stop
|
||||
{{accept}}
|
||||
{{content-type}}
|
||||
|
||||
{
|
||||
"Id": 4900,
|
||||
"ProcessName": "Taskmgr"
|
||||
}
|
||||
89
src/proc.go
Normal file
89
src/proc.go
Normal file
@@ -0,0 +1,89 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"strings"
|
||||
|
||||
"github.com/shirou/gopsutil/v4/process"
|
||||
"golang.org/x/text/encoding/simplifiedchinese"
|
||||
)
|
||||
|
||||
type Process struct {
|
||||
Pid int32 `json:"Id"`
|
||||
Name string `json:"ProcessName"`
|
||||
Exe string `json:"Path"`
|
||||
Title string `json:"MainWindowTitle"`
|
||||
}
|
||||
|
||||
func ListProcess(filter string) []Process {
|
||||
ps := []Process{}
|
||||
v, _ := process.Processes()
|
||||
for _, value := range v {
|
||||
name, _ := value.Name()
|
||||
exe, _ := value.Exe()
|
||||
|
||||
if name == "" {
|
||||
continue
|
||||
}
|
||||
if value.Pid <= 10 {
|
||||
continue
|
||||
}
|
||||
if strings.Contains(exe, "C:\\Windows") {
|
||||
continue
|
||||
}
|
||||
if !strings.Contains(strings.ToLower(name), strings.ToLower(filter)) {
|
||||
continue
|
||||
}
|
||||
|
||||
title := GetMainWindowTitle(value.Pid)
|
||||
|
||||
p := Process{
|
||||
Pid: value.Pid,
|
||||
Name: name,
|
||||
Exe: exe,
|
||||
Title: title,
|
||||
}
|
||||
ps = append(ps, p)
|
||||
}
|
||||
return ps
|
||||
}
|
||||
|
||||
// TODO filter 参数还有一些问题,无法获取
|
||||
func ListProcessesUsingPowerShell(filter string) []Process {
|
||||
ps := []Process{}
|
||||
command := fmt.Sprintf("Get-Process *%s* | Where-Object {$_.MainWindowTitle} | Select-Object -Property Id,ProcessName,MainWindowTitle,Path | ConvertTo-Json -Compress ", filter)
|
||||
fmt.Println(command)
|
||||
result := exec.Command("powershell", "-Command", command)
|
||||
output, _ := result.CombinedOutput()
|
||||
// str := ConvertByte2String(output, "GB18030")
|
||||
b, _ := simplifiedchinese.GB18030.NewDecoder().Bytes(output)
|
||||
err := json.Unmarshal(b, &ps)
|
||||
if err != nil {
|
||||
println(err)
|
||||
}
|
||||
return ps
|
||||
}
|
||||
|
||||
func StopProcess(pid int32) (Process, error) {
|
||||
p, err := process.NewProcess(pid)
|
||||
|
||||
if err != nil {
|
||||
return Process{}, err
|
||||
}
|
||||
|
||||
name, _ := p.Name()
|
||||
exe, _ := p.Exe()
|
||||
ps := Process{
|
||||
Pid: p.Pid,
|
||||
Name: name,
|
||||
Exe: exe,
|
||||
}
|
||||
|
||||
err = p.Terminate()
|
||||
if err != nil {
|
||||
return ps, err
|
||||
}
|
||||
return ps, nil
|
||||
}
|
||||
74
src/services.go
Normal file
74
src/services.go
Normal file
@@ -0,0 +1,74 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type Service struct {
|
||||
Port int
|
||||
}
|
||||
|
||||
func (s Service) Run() {
|
||||
r := gin.Default()
|
||||
|
||||
r.GET("/", func(c *gin.Context) {
|
||||
// 重定向到 /ping
|
||||
c.Redirect(http.StatusMovedPermanently, "/ping")
|
||||
})
|
||||
|
||||
r.GET("/ping", func(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"code": 0,
|
||||
"data": gin.H{
|
||||
"message": "pong",
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
r.GET("/list", func(c *gin.Context) {
|
||||
name := c.Query("name")
|
||||
ps := ListProcess(name)
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"code": 0,
|
||||
"data": ps,
|
||||
})
|
||||
})
|
||||
|
||||
r.GET("/listps", func(c *gin.Context) {
|
||||
name := c.Query("name")
|
||||
ps := ListProcessesUsingPowerShell(name)
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"code": 0,
|
||||
"data": ps,
|
||||
})
|
||||
})
|
||||
|
||||
r.POST("/stop", func(c *gin.Context) {
|
||||
var p Process
|
||||
if err := c.ShouldBindJSON(&p); err == nil {
|
||||
ps, err := StopProcess(p.Pid)
|
||||
if err == nil {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"code": 0,
|
||||
"data": gin.H{
|
||||
"message": "A termination signal has been sent",
|
||||
"process": ps,
|
||||
},
|
||||
})
|
||||
} else {
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
"code": 1,
|
||||
"data": gin.H{
|
||||
"message": "An unknown error occurred, see error for details",
|
||||
"error": err.Error(),
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
r.Run(":" + strconv.Itoa(s.Port))
|
||||
}
|
||||
34
src/windowtitle.go
Normal file
34
src/windowtitle.go
Normal file
@@ -0,0 +1,34 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"os/exec"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/text/encoding/simplifiedchinese"
|
||||
)
|
||||
|
||||
func GetMainWindowTitle(pid int32) string {
|
||||
id := strconv.Itoa(int(pid))
|
||||
command := "Get-Process -PID " + id + " | Format-List -Property MainWindowTitle"
|
||||
cmd := exec.Command("powershell.exe", "-command", command)
|
||||
output, _ := cmd.CombinedOutput()
|
||||
str := ConvertByte2String(output, "GB18030")
|
||||
str = strings.ReplaceAll(str, "\r\n", "")
|
||||
str = strings.ReplaceAll(str, "MainWindowTitle : ", "")
|
||||
return str
|
||||
}
|
||||
|
||||
func ConvertByte2String(byte []byte, charset string) string {
|
||||
var str string
|
||||
switch charset {
|
||||
case "GB18030":
|
||||
var decodeBytes, _ = simplifiedchinese.GB18030.NewDecoder().Bytes(byte)
|
||||
str = string(decodeBytes)
|
||||
case "UTF8":
|
||||
fallthrough
|
||||
default:
|
||||
str = string(byte)
|
||||
}
|
||||
return str
|
||||
}
|
||||
Reference in New Issue
Block a user