Golang 화면보호기 방지, idle 방지, 절전모드 방기기능
by 개발자   2024-11-20 10:06:42   조회수:20
package main

import (
    _ "embed"
    "fmt"
    "os"
    "syscall"
    "time"
    "unsafe"

    "github.com/getlantern/systray"

    _ "embed"
)

var isRunning = true // Toggle to control the idle prevention

var (
    user32             = syscall.NewLazyDLL("user32.dll")
    kernel32           = syscall.NewLazyDLL("kernel32.dll")
    keyboardEvent      = user32.NewProc("keybd_event")
    mouseEvent         = user32.NewProc("mouse_event")
    setCursorPos       = user32.NewProc("SetCursorPos")
    getCursorPos       = user32.NewProc("GetCursorPos")
    setThreadExecution = kernel32.NewProc("SetThreadExecutionState")
)

const (
    KEYEVENTF_KEYUP     = 0x2
    VK_F15              = 0x7E
    MOUSEEVENTF_MOVE    = 0x0001
    ES_CONTINUOUS       = 0x80000000
    ES_SYSTEM_REQUIRED  = 0x00000001
    ES_DISPLAY_REQUIRED = 0x00000002
)

type POINT struct {
    X, Y int32
}

//go:embed assets/icon.ico
var iconData []byte

func main() {
    // Setup system tray
    fmt.Println("Idle prevention started.")
    systray.Run(onReady, onExit)
}
func onReady() {
    // Load an icon (replace "icon.ico" with your actual icon path)
    systray.SetIcon(iconData)
    systray.SetTitle("Idle Prevention")
    systray.SetTooltip("Prevents system from going idle")

    // Add menu items
    mToggle := systray.AddMenuItem("Toggle Prevention", "Start/Stop idle prevention")
    mQuit := systray.AddMenuItem("Quit", "Exit the application")

    // Handle menu interactions
    go func() {
        for {
            select {
            case <-mToggle.ClickedCh:
                isRunning = !isRunning
                if isRunning {
                    fmt.Println("Idle prevention started.")
                } else {
                    fmt.Println("Idle prevention paused.")
                }
            case <-mQuit.ClickedCh:
                systray.Quit()
            }
        }
    }()

    // Start the idle prevention logic
    go idlePreventionLoop()
}

func onExit() {
    // Reset sleep prevention state on exit
    resetSleepState()
    fmt.Println("Application exited.")
}

func idlePreventionLoop() {
    ticker := time.NewTicker(1 * time.Minute)
    defer ticker.Stop()

    for {
        if !isRunning {
            time.Sleep(1 * time.Second)
            continue
        }

        select {
        case <-ticker.C:
            preventSleep()
            simulateKeyPress()
            simulateMouseMove()
            fmt.Printf("Activity simulated at: %s\n", time.Now().Format("15:04:05"))
        }
    }
}

// Simulated functions
func preventSleep() {
    // Prevent system sleep
    fmt.Println("Preventing sleep...")
    // Prevent system sleep, display sleep, and enable continuous mode
    setThreadExecution.Call(ES_CONTINUOUS | ES_SYSTEM_REQUIRED | ES_DISPLAY_REQUIRED)
}

func simulateKeyPress() {
    // Simulate key press
    fmt.Println("Simulating key press...")
    keyboardEvent.Call(VK_F15, 0, 0, 0)
    keyboardEvent.Call(VK_F15, 0, KEYEVENTF_KEYUP, 0)
}

func simulateMouseMove() {
    // Simulate mouse movement
    fmt.Println("Simulating mouse movement...")
    var point POINT
    getCursorPos.Call(uintptr(unsafe.Pointer(&point)))

    // Move mouse in a small square pattern
    moves := []struct{ x, y int32 }{
        {point.X + 1, point.Y},
        {point.X + 1, point.Y + 1},
        {point.X, point.Y + 1},
        {point.X, point.Y},
    }

    for _, move := range moves {
        setCursorPos.Call(uintptr(move.x), uintptr(move.y))
        time.Sleep(100 * time.Millisecond)
    }
}

func resetSleepState() {
    // Reset sleep prevention state
    fmt.Println("Resetting sleep prevention state...")
    // Prevent system sleep, display sleep, and enable continuous mode
    setThreadExecution.Call(ES_CONTINUOUS | ES_SYSTEM_REQUIRED | ES_DISPLAY_REQUIRED)
}

func getIcon(path string) []byte {
    // Load an .ico file for the system tray icon
    file, err := os.ReadFile(path)
    if err != nil {
        fmt.Printf("Failed to load icon: %v\n", err)
        return nil
    }
    return file
}