你如何保持机器清醒?

时间:2008-09-09 20:50:12

标签: java windows macos cross-platform operating-system

我有一个用Java编写的服务器软件在Windows和OS X上运行。(它不是在服务器上运行,而只是普通用户的PC - 类似于torrent客户端。)我想要用于向操作系统发出信号的软件,​​以便在机器处于活动状态时保持机器处于唤醒状态(防止其进入睡眠模式)。

当然我不希望有一个跨平台的解决方案,但我希望有一些非常小的C程序/脚本,我的应用程序可以产生,以通知操作系统保持清醒。

有什么想法吗?

19 个答案:

答案 0 :(得分:27)

我使用此代码来防止工作站锁定。它目前只设置为每分钟移动一次鼠标,你可以很容易地调整它。

这是一个黑客,而不是一个优雅的解决方案。

import java.awt.*;
import java.util.*;
public class Hal{

    public static void main(String[] args) throws Exception{
        Robot hal = new Robot();
        Random random = new Random();
        while(true){
            hal.delay(1000 * 60);
            int x = random.nextInt() % 640;
            int y = random.nextInt() % 480;
            hal.mouseMove(x,y);
        }
    }
}

答案 1 :(得分:21)

我听说过人们收到一个大型低音炮的故事,然后将盒盖盖在顶部。然后,您可以将鼠标放在框中并调高音乐。最好是有很多低音的东西会让鼠标四处移动。

答案 2 :(得分:14)

在Windows上,使用SystemParametersInfo功能。这是一种瑞士军队风格的功能,可以让你获得/设置各种系统设置。

要禁用屏幕关闭,例如:

SystemParametersInfo( SPI_SETPOWEROFFACTIVE, 0, NULL, 0 );

请务必在完成后将其重新设置......

答案 3 :(得分:6)

我有一种非常强力的技术,即在x方向上移动鼠标1点,然后每3分钟移回一次。

我可能会有一个更优雅的解决方案,但这是一个快速解决方案。

答案 4 :(得分:6)

在上面添加scarcher2的代码片段并仅将鼠标移动1个像素。我已经移动了两次鼠标,以便即使指针处于极端状态也会发生一些变化:

while(true){
            hal.delay(1000 * 30);       
            Point pObj = MouseInfo.getPointerInfo().getLocation();
            System.out.println(pObj.toString() + "x>>" + pObj.x + "  y>>" + pObj.y);
            hal.mouseMove(pObj.x + 1, pObj.y + 1);  
            hal.mouseMove(pObj.x - 1, pObj.y - 1);
            pObj = MouseInfo.getPointerInfo().getLocation();
            System.out.println(pObj.toString() + "x>>" + pObj.x + "  y>>" + pObj.y);
        }

答案 5 :(得分:4)

并非所有建议来回移动鼠标都会让用户疯狂吗?我知道我会删除任何可以隔离它的应用程序。

答案 6 :(得分:3)

一个更简洁的解决方案是使用 JNA 来接入原生 OS API。在运行时检查您的平台,如果它恰好是 Windows,那么以下将起作用:

import com.sun.jna.Native;
import com.sun.jna.Structure;
import com.sun.jna.Structure.FieldOrder;
import com.sun.jna.platform.win32.WTypes.LPWSTR;
import com.sun.jna.platform.win32.WinBase;
import com.sun.jna.platform.win32.WinDef.DWORD;
import com.sun.jna.platform.win32.WinDef.ULONG;
import com.sun.jna.platform.win32.WinNT.HANDLE;
import com.sun.jna.win32.StdCallLibrary;

/**
 * Power management.
 *
 * @see <a href="https://stackoverflow.com/a/20996135/14731">https://stackoverflow.com/a/20996135/14731</a>
 */
public enum PowerManagement
{
    INSTANCE;

    @FieldOrder({"version", "flags", "simpleReasonString"})
    public static class REASON_CONTEXT extends Structure
    {
        public static class ByReference extends REASON_CONTEXT implements Structure.ByReference
        {
        }

        public ULONG version;
        public DWORD flags;
        public LPWSTR simpleReasonString;
    }

    private interface Kernel32 extends StdCallLibrary
    {
        HANDLE PowerCreateRequest(REASON_CONTEXT.ByReference context);

        /**
         * @param powerRequestHandle the handle returned by {@link #PowerCreateRequest(REASON_CONTEXT.ByReference)}
         * @param requestType        requestType is the ordinal value of {@link PowerRequestType}
         * @return true on success
         */
        boolean PowerSetRequest(HANDLE powerRequestHandle, int requestType);

        /**
         * @param powerRequestHandle the handle returned by {@link #PowerCreateRequest(REASON_CONTEXT.ByReference)}
         * @param requestType        requestType is the ordinal value of {@link PowerRequestType}
         * @return true on success
         */
        boolean PowerClearRequest(HANDLE powerRequestHandle, int requestType);

        enum PowerRequestType
        {
            PowerRequestDisplayRequired,
            PowerRequestSystemRequired,
            PowerRequestAwayModeRequired,
            PowerRequestMaximum
        }
    }

    private final Kernel32 kernel32;
    private HANDLE handle = null;

    PowerManagement()
    {
        // Found in winnt.h
        ULONG POWER_REQUEST_CONTEXT_VERSION = new ULONG(0);
        DWORD POWER_REQUEST_CONTEXT_SIMPLE_STRING = new DWORD(0x1);

        kernel32 = Native.load("kernel32", Kernel32.class);
        REASON_CONTEXT.ByReference context = new REASON_CONTEXT.ByReference();
        context.version = POWER_REQUEST_CONTEXT_VERSION;
        context.flags = POWER_REQUEST_CONTEXT_SIMPLE_STRING;
        context.simpleReasonString = new LPWSTR("Your reason for changing the power setting");
        handle = kernel32.PowerCreateRequest(context);
        if (handle == WinBase.INVALID_HANDLE_VALUE)
            throw new AssertionError(Native.getLastError());
    }

    /**
     * Prevent the computer from going to sleep while the application is running.
     */
    public void preventSleep()
    {
        if (!kernel32.PowerSetRequest(handle, Kernel32.PowerRequestType.PowerRequestSystemRequired.ordinal()))
            throw new AssertionError("PowerSetRequest() failed");
    }

    /**
     * Allow the computer to go to sleep.
     */
    public void allowSleep()
    {
        if (!kernel32.PowerClearRequest(handle, Kernel32.PowerRequestType.PowerRequestSystemRequired.ordinal()))
            throw new AssertionError("PowerClearRequest() failed");
    }
}

然后当用户运行 powercfg /requests 时,他们看到:

SYSTEM:
[PROCESS] \Device\HarddiskVolume1\Users\Gili\.jdks\openjdk-15.0.2\bin\java.exe
Your reason for changing the power setting

您应该能够为 macOS 和 Linux 执行类似的操作。

答案 7 :(得分:2)

禁用服务器上的电源管理会不会更容易?可能有人认为服务器不应该进入powersave模式?

答案 8 :(得分:2)

在Visual Studio中创建一个简单的表单。 从工具栏中,将Timer控件拖到窗体上。 在Init代码中,将定时器间隔设置为60秒(60000 ms。)。 使用以下代码“SendKeys.Send(”{F15}“)实现计时器回调;” 运行新程序。

无需移动鼠标。

编辑:至少在我的陆军工作站上,只是以编程方式生成鼠标和关键信息不足以让我的工作站登录并唤醒。早期的Java Robot类海报正在走上正轨。 JAVA Robot在OS的HAL(硬件抽象层)之上或之下工作但是我重新创建并测试了Java / Robot解决方案并且它不起作用 - 直到我在代码中添加了Robot.keyPress(123)。

答案 9 :(得分:2)

您可以使用程序Caffeine caffiene让您的工作站保持清醒状态。您可以通过os X中的open命令运行该程序。

答案 10 :(得分:2)

我一直在使用pmset来控制我的Mac上的睡眠模式一段时间,并且它很容易集成。这是一个粗略的例子,说明如何从Java调用该程序来禁用/启用睡眠模式。请注意,您需要root权限才能运行pmset,因此您需要它们才能运行此程序。

import java.io.BufferedInputStream;
import java.io.IOException;

/**
 * Disable sleep mode (record current setting beforehand), and re-enable sleep
 * mode. Works with Mac OS X using the "pmset" command.
 */
public class SleepSwitch {

    private int sleepTime = -1;

    public void disableSleep() throws IOException {
        if (sleepTime != -1) {
            // sleep time is already recorded, assume sleep is disabled
            return;
        }

        // query pmset for the current setting
        Process proc = Runtime.getRuntime().exec("pmset -g");
        BufferedInputStream is = new BufferedInputStream(proc.getInputStream());
        StringBuffer output = new StringBuffer();
        int c;
        while ((c = is.read()) != -1) {
            output.append((char) c);
        }
        is.close();

        // parse the current setting and store the sleep time
        String outString = output.toString();
        String setting = outString.substring(outString.indexOf(" sleep\t")).trim();
        setting = setting.substring(7, setting.indexOf(" ")).trim();
        sleepTime = Integer.parseInt(setting);

        // set the sleep time to zero (disable sleep)
        Runtime.getRuntime().exec("pmset sleep 0");
    }

    public void enableSleep() throws IOException {
        if (sleepTime == -1) {
            // sleep time is not recorded, assume sleep is enabled
            return;
        }

        // set the sleep time to the previously stored value
        Runtime.getRuntime().exec("pmset sleep " + sleepTime);

        // reset the stored sleep time
        sleepTime = -1;
    }
}

答案 11 :(得分:1)

此代码将指针移动到已经存在的位置,因此用户不会注意到任何差异。

while (true) {
    Thread.sleep(180000);//this is how long before it moves
    Point mouseLoc = MouseInfo.getPointerInfo().getLocation();
    Robot rob = new Robot();
    rob.mouseMove(mouseLoc.x, mouseLoc.y);
}

答案 12 :(得分:1)

在OS X上,只生成caffeinate。这将阻止系统在caffeinate终止之前暂停。

答案 13 :(得分:1)

我只是做一个移动鼠标的功能(或下载免费赠品应用程序)。不雅,但很容易。

答案 14 :(得分:1)

这样可行:

public class Utils {
    public static void main(String[] args) throws AWTException {
        Robot rob = new Robot();
        PointerInfo ptr = null;
        while (true) {
            rob.delay(4000);  // Mouse moves every 4 seconds
            ptr = MouseInfo.getPointerInfo();
            rob.mouseMove((int) ptr.getLocation().getX() + 1, (int) ptr.getLocation().getY() + 1);
        }
    }
}

答案 15 :(得分:1)

已完成的批处理文件可以生成Java代码,对其进行编译,清理生成的文件并在后台运行。.(笔记本电脑上需要jdk)

只需运行此Bat文件;)

@echo off
setlocal

rem rem if JAVA is set and run from :startapp labeled section below, else the program exit through :end labeled section.
if not "[%JAVA_HOME%]"=="[]" goto start_app
echo. JAVA_HOME not set. Application will not run!
goto end


:start_app
echo. Using java in %JAVA_HOME%
rem writes below code to Energy.java file.
@echo import java.awt.MouseInfo; > Energy.java
@echo import java.awt.Point; >> Energy.java
@echo import java.awt.Robot; >> Energy.java
@echo //Mouse Movement Simulation >> Energy.java
@echo public class Energy { >> Energy.java
@echo     public static void main(String[] args) throws Exception { >> Energy.java
@echo         Robot energy = new Robot(); >> Energy.java
@echo         while (true) { >> Energy.java
@echo             energy.delay(1000 * 60); >> Energy.java
@echo             Point pObj = MouseInfo.getPointerInfo().getLocation(); >> Energy.java
@echo             Point pObj2 = pObj;  >> Energy.java
@echo             System.out.println(pObj.toString() + "x>>" + pObj.x + "  y>>" + pObj.y); >> Energy.java
@echo             energy.mouseMove(pObj.x + 10, pObj.y + 10); >> Energy.java
@echo             energy.mouseMove(pObj.x - 10, pObj.y - 10); >> Energy.java
@echo             energy.mouseMove(pObj2.x, pObj.y); >> Energy.java
@echo             pObj = MouseInfo.getPointerInfo().getLocation(); >> Energy.java
@echo             System.out.println(pObj.toString() + "x>>" + pObj.x + "  y>>" + pObj.y); >> Energy.java
@echo         } >> Energy.java
@echo     } >> Energy.java
@echo } >> Energy.java

rem compile java code.
javac Energy.java
rem run java application in background.
start javaw Energy
echo. Your Secret Energy program is running...
goto end

:end
rem clean if files are created.
pause
del "Energy.class"
del "Energy.java"

答案 16 :(得分:1)

在计时器内运行命令,例如ping服务器..

答案 17 :(得分:1)

要使用用户 Gili 提供的使用 JNA 的 Windows 解决方案,这里是 MacOS 的 JNA 解决方案。

一、JNA库接口:

import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.platform.mac.CoreFoundation;
import com.sun.jna.ptr.IntByReference;

public interface ExampleIOKit extends Library {
    ExampleIOKit INSTANCE = Native.load("IOKit", ExampleIOKit.class);

    CoreFoundation.CFStringRef kIOPMAssertPreventUserIdleSystemSleep = CoreFoundation.CFStringRef.createCFString("PreventUserIdleSystemSleep");
    CoreFoundation.CFStringRef kIOPMAssertPreventUserIdleDisplaySleep = CoreFoundation.CFStringRef.createCFString("PreventUserIdleDisplaySleep");

    int kIOReturnSuccess = 0;

    int kIOPMAssertionLevelOff = 0;
    int kIOPMAssertionLevelOn = 255;

    int IOPMAssertionCreateWithName(CoreFoundation.CFStringRef assertionType,
                                    int assertionLevel,
                                    CoreFoundation.CFStringRef reasonForActivity,
                                    IntByReference assertionId);

    int IOPMAssertionRelease(int assertionId);
}

以下是调用 JNA 方法打开或关闭睡眠预防的示例:

public class Example {
    private static final Logger _log = LoggerFactory.getLogger(Example.class);

    private int sleepPreventionAssertionId = 0;

    public void updateSleepPrevention(final boolean isEnabled) {
        if (isEnabled) {
            if (sleepPreventionAssertionId == 0) {
                final var assertionIdRef = new IntByReference(0);
                final var reason = CoreFoundation.CFStringRef.createCFString(
                    "Example preventing display sleep");
                final int result = ExampleIOKit.INSTANCE.IOPMAssertionCreateWithName(
                    ExampleIOKit.kIOPMAssertPreventUserIdleDisplaySleep,
                    ExampleIOKit.kIOPMAssertionLevelOn, reason, assertionIdRef);
                if (result == ExampleIOKit.kIOReturnSuccess) {
                    _log.info("Display sleep prevention enabled");
                    sleepPreventionAssertionId = assertionIdRef.getValue();
                }
                else {
                    _log.error("IOPMAssertionCreateWithName returned {}", result);
                }
            }
        }
        else {
            if (sleepPreventionAssertionId != 0) {
                final int result = ExampleIOKit.INSTANCE.IOPMAssertionRelease(sleepPreventionAssertionId);
                if (result == ExampleIOKit.kIOReturnSuccess) {
                    _log.info("Display sleep prevention disabled");
                }
                else {
                    _log.error("IOPMAssertionRelease returned {}", result);
                }
                sleepPreventionAssertionId = 0;
            }
        }
    }
}

答案 18 :(得分:0)

我用来避免“ Windows桌面自动锁定”的一种简单方法是每6秒“打开/关闭NumLock”。

这里有一个Java程序可以打开/关闭NumLock。

import java.util.*;
import java.awt.*;
import java.awt.event.*;

public class NumLock extends Thread {
  public void run() {
    try {
    boolean flag = true;
    do {
        flag = !flag;

        Thread.sleep(6000);
        Toolkit.getDefaultToolkit().setLockingKeyState(KeyEvent. VK_NUM_LOCK, flag);
    }
    while(true);
    }
    catch(Exception e) {}
  }

  public static void main(String[] args) throws Exception {
    new NumLock().start();
  }
}

在单独的命令提示符下运行此Java程序; :-)