80 lines
1.7 KiB
Go
80 lines
1.7 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
"os"
|
|
"os/signal"
|
|
"time"
|
|
|
|
"github.com/postfinance/single"
|
|
"github.com/shirou/gopsutil/process"
|
|
"golang.org/x/sys/windows"
|
|
)
|
|
|
|
const (
|
|
memThreshold = 512 * 1024 * 1024
|
|
selfPriority = windows.IDLE_PRIORITY_CLASS
|
|
targetPriority = windows.HIGH_PRIORITY_CLASS
|
|
)
|
|
|
|
func setPriority(pid int32, class uint32) error {
|
|
h, err := windows.OpenProcess(windows.PROCESS_SET_INFORMATION, false, uint32(pid))
|
|
if err != nil {
|
|
return fmt.Errorf("open process %d: %w", pid, err)
|
|
}
|
|
defer windows.CloseHandle(h)
|
|
return windows.SetPriorityClass(h, class)
|
|
}
|
|
|
|
func main() {
|
|
lock, err := single.New("autoPriority")
|
|
if err != nil {
|
|
log.Fatalf("create lock: %v", err)
|
|
}
|
|
if err := lock.Lock(); err != nil {
|
|
windows.MessageBox(0,
|
|
windows.StringToUTF16Ptr("The program is already running.\nYou can close it via the Task Manager."),
|
|
windows.StringToUTF16Ptr("autoPriority"),
|
|
windows.MB_OK|windows.MB_ICONWARNING,
|
|
)
|
|
os.Exit(1)
|
|
}
|
|
defer lock.Unlock()
|
|
|
|
if err := setPriority(int32(os.Getpid()), selfPriority); err != nil {
|
|
log.Printf("set self priority: %v", err)
|
|
}
|
|
|
|
sig := make(chan os.Signal, 1)
|
|
signal.Notify(sig, os.Interrupt)
|
|
|
|
tk := time.NewTicker(time.Minute)
|
|
defer tk.Stop()
|
|
|
|
for {
|
|
select {
|
|
case <-sig:
|
|
log.Println("exit")
|
|
return
|
|
case <-tk.C:
|
|
procs, err := process.Processes()
|
|
if err != nil {
|
|
log.Printf("list processes: %v", err)
|
|
continue
|
|
}
|
|
for _, p := range procs {
|
|
m, err := p.MemoryInfo()
|
|
if err != nil {
|
|
continue
|
|
}
|
|
if m.RSS >= memThreshold {
|
|
if err := setPriority(p.Pid, targetPriority); err != nil {
|
|
log.Printf("PID %d: %v", p.Pid, err)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|