你如何保持机器清醒?

Fra*_*ger 27 java windows macos operating-system cross-platform

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

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

有任何想法吗?

ScA*_*er2 29

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

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

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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 为什么不像@Keng提到的那样将鼠标移动1个像素?这似乎会让用户疯狂. (7认同)
  • 如果安装了Java的无头版本(仅Linux),这将不起作用。 (3认同)
  • 您可以这样做,但我不需要。我刚刚发布了我正在使用的代码。我花了大约2分钟才能写完,而且我不需要更改它。如果您想发布修改后的版本以将其移动一个像素,那就太酷了。 (2认同)

Mat*_*ard 14

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

要禁用屏幕关闭,例如:

SystemParametersInfo( SPI_SETPOWEROFFACTIVE, 0, NULL, 0 );
Run Code Online (Sandbox Code Playgroud)

你完成后一定要把它放回去......

  • 非常糟糕的主意.如果程序崩溃,那么您只是在未经许可的情况下更改了用户设置.您应该处理WM_POWERBROADCAST消息. (3认同)
  • 这肯定是使用这种方法的危险; 通过创建一个在其构造函数中进行此调用的类,并在析构函数中重置它,可以稍微减轻(在C++中).处理WM_POWERBROADCAST事件也可能有效,但仅适用于某些类型的Windows. (2认同)

Gil*_*ili 8

一个更简洁的解决方案是使用 JNA 来利用本机操作系统 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="/sf/answers/1469729481/">/sf/answers/1469729481/</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");
    }
}
Run Code Online (Sandbox Code Playgroud)

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

SYSTEM:
[PROCESS] \Device\HarddiskVolume1\Users\Gili\.jdks\openjdk-15.0.2\bin\java.exe
Your reason for changing the power setting
Run Code Online (Sandbox Code Playgroud)

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

  • 我注意到的一件事是,“PowerSetRequest”方法会增加一个计数器。因此,如果您调用该函数两次,则需要两次相应的“PowerClearRequest”调用来将计数器再次递减至 0,以允许操作系统进入睡眠状态。我通过保留一个布尔标志来防止这种情况发生,该标志表明我已经调用了“PowerSetRequest”。另外,我有一个清理方法来释放句柄。我通过调用“kernel32.CloseHandle(handle)”来完成此操作。这需要我向“Kernel32”接口添加一个“boolean CloseHandle(HANDLE handle)”方法。 (2认同)

Ken*_*eng 6

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

可能有一个更优雅的解决方案,但它是一个快速解决方案.


asl*_*oob 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);
        }
Run Code Online (Sandbox Code Playgroud)

  • 你实际上可以将它移动到它所在的位置`hal.mouseMove(pObj.x, pObj.y);` (2认同)

zig*_*don 5

所有来回移动鼠标的建议不会让用户发疯吗?我知道我会尽快删除任何会这样做的应用程序。

  • 将它移动一个像素对任何人来说都不会引起注意,但是机器人和机器人只是 devnull 沮丧,所以你一切都好。 (5认同)