make windows csminer also detect active screensaver

This commit is contained in:
cryptonote-social 2020-07-26 16:07:02 -07:00
parent 0a176b48b4
commit 1a10583912
2 changed files with 72 additions and 25 deletions

View File

@ -4,8 +4,8 @@ SYNOPSIS
csminer from https://cryptonote.social is an easy-to-use CPU miner for Monero intended to provide
"set it and forget it" mining for your existing laptop and desktop machines. By default, csminer
mines with a single thread, and only when Gnome dims the screen. It can be configured to always
mine or mine with more threads using the options described below.
mines with a single thread, and only when the screen is locked or the screensaver is running. It
can be configured to always mine or mine with more threads using the options described below.
USAGE
@ -16,7 +16,7 @@ All arguments are optional:
-user <string>
your pool username from https://cryptonote.social/xmr (default "donate-getmonero-org")
-saver <bool>
mine only when screen is locked (default true)
mine only when screen is locked or the screensaver is running (default true)
-exclude <string>
pause mining during the specified hours. Format is XX-YY where XX and YY are hours of
the day designated in 24 hour time. For example, -exclude=11-16 will pause mining betwen
@ -36,6 +36,9 @@ pool stats in the command shell.
Tips:
Under Windows Power & Sleep settings, set "When plugged in, PC goes to
sleep after" to Never.
For best performance, if csminer reports it's unable to allocate hugepages, try restarting your
machine and starting csminer before running anything else.
@ -66,21 +69,7 @@ username and you can login with the username alone, e.g.:
Implementation
csminer utilizes the RandomX implementation from https://github.com/tevador/RandomX and will
perform similarly to other mining software based on this library such as xmrig. It will attempt to
use hugepages if available, so for optimal performance confirm hugepages is enabled on your
machine. If hugepages is enabled but the miner reports it's unable to allocate them, try restarting
your machine.
Windows version: csminer for Windows monitors session notifications for session lock messages and
should activate the miner whenever the screen is locked.
Mac/OSX version: csminer for OSX polls the lock screen state every 10 seconds and should activate
the miner shortly after the screen locks. Confirm you have selected "prevent the computer from
sleeping" in Energy Saver settings so the computer can mine while connected to power.
Linux/Gnome version: csminer for Linux monitors Gnome screensaver events, and should activate the miner
whenever the screen "dims".
perform similarly to other mining software based on this library such as xmrig.
Feedback & Bug Reports

View File

@ -5,25 +5,32 @@ package main
// main() for the Windows version of csminer with support for Windows locks screen monitoring.
import (
"time"
"syscall"
"unsafe"
"github.com/brunoqc/go-windows-session-notifications"
"github.com/cryptonote-social/csminer"
"github.com/cryptonote-social/csminer/crylog"
"golang.org/x/sys/windows"
)
type WinScreenStater struct {
lockedOnStartup bool
}
// We assume the screen is active when the miner is started. This may
// not hold if someone is running the miner from an auto-start script?
// TODO: On startup check if someone is logged in and if not assume screen
// is locked.
func GetScreenStateChannel() (chan bool, error) {
ret := make(chan bool)
func (ss *WinScreenStater) GetScreenStateChannel() (chan csminer.ScreenState, error) {
ret := make(chan csminer.ScreenState)
chanMessages := make(chan session_notifications.Message, 100)
chanClose := make(chan int)
go func() {
// TODO: Also monitor for ac vs battery power state
currentlyLocked := false
isIdle := false
for {
select {
case m := <-chanMessages:
@ -32,14 +39,42 @@ func GetScreenStateChannel() (chan bool, error) {
switch m.Param {
case session_notifications.WTS_SESSION_LOCK:
crylog.Info("win session locked")
ret <- true
currentlyLocked = true
if !isIdle {
isIdle = true
ret <- csminer.ScreenState(csminer.SCREEN_IDLE)
}
case session_notifications.WTS_SESSION_UNLOCK:
crylog.Info("win session unlocked")
ret <- false
currentlyLocked = false
if isIdle {
isIdle = false
ret <- csminer.ScreenState(csminer.SCREEN_ACTIVE)
}
default:
}
}
close(m.ChanOk)
case <-time.After(10*time.Second):
if currentlyLocked {
continue
}
saver, err := isScreenSaverRunning()
if err != nil {
crylog.Error("failed to get screensaver state:", err)
continue
}
if saver != isIdle {
if saver {
crylog.Info("Detected running screensaver")
isIdle = true
ret <- csminer.ScreenState(csminer.SCREEN_IDLE)
} else {
crylog.Info("No longer detecting active screensaver")
isIdle = false
ret <- csminer.ScreenState(csminer.SCREEN_ACTIVE)
}
}
}
}
crylog.Error("win screen stater loop exit")
@ -50,5 +85,28 @@ func GetScreenStateChannel() (chan bool, error) {
}
func main() {
csminer.MultiMain(WinScreenStater{}, csminer.VERSION_STRING+" (win)")
ss := WinScreenStater{ lockedOnStartup: false }
csminer.MultiMain(&ss, "csminer "+csminer.VERSION_STRING+" (win)")
}
var libuser32 *windows.LazyDLL
func init() {
libuser32 = windows.NewLazySystemDLL("user32.dll")
}
func isScreenSaverRunning() (bool, error) {
systemParametersInfo := libuser32.NewProc("SystemParametersInfoW")
var uiAction, uiParam uint32
uiAction = 0x0072 //SPI_GETSCREENSAVERRUNNING
var pvParam unsafe.Pointer
var fWinIni uint32
var retVal bool
pvParam = unsafe.Pointer(&retVal)
res, _, err := syscall.Syscall6(systemParametersInfo.Addr(), 4, uintptr(uiAction), uintptr(uiParam), uintptr(pvParam), uintptr(fWinIni), 0, 0)
if res == 0 {
return false, err
}
return retVal, nil
}