【问题标题】:Why does this Java Robot code shutdown my computer?为什么这个 Java Robot 代码会关闭我的计算机?
【发布时间】:2015-01-25 07:33:47
【问题描述】:

我正在用java.awt.Robot 类摆弄一些基于自动化的代码。代码运行得很完美,但是当我更改了一些东西时,其中一些甚至没有使用main 运行,代码似乎部分完成了它的任务,但随后计算机开始了它的关机序列,关闭了所有程序。我只能通过单击“等待...”屏幕上的取消来停止它。你们有谁知道为什么下面的代码会导致这种情况发生?

同样,在我添加/删除/更改某些内容之前,这段代码运行良好。

我将按原样粘贴它,以防有任何特定原因导致此问题。抱歉,帖子太长了。

package _defaultpackage;

import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;

import static java.awt.event.InputEvent.*;
import static java.awt.event.KeyEvent.*;//static import means we can type VK_1 instead of KeyEvent.VK_1

public class JavaRobot {

    static Robot robot;

    public static void main(String[] args) {

        try {robot = new Robot();} catch (Exception e) {}

        robot.setAutoDelay(30);
        robot.setAutoWaitForIdle(true);

        combination(VK_WINDOWS, VK_R);

        paste("notepad");

        hit(VK_ENTER);

        paste("Hello World!\n123");

        robot.delay(2000);

        combination(VK_ALT, VK_F4);

        hit(VK_RIGHT);
        hit(VK_ENTER);

        robot.setAutoDelay(10);
        for (int i = 0; i < 700; i++) {
            robot.mouseMove(i, i);
        }

        System.out.println("Done.");
    }

    static void leftClick() {
        robot.mousePress(BUTTON1_MASK);
        robot.delay(200);
        robot.mouseRelease(BUTTON1_MASK);
        robot.delay(200);
    }

    static void type(String s) {
        byte[] bytes = s.getBytes();
        for (byte b : bytes) {
            int code = b;
            // keycode only handles [A-Z] (which is ASCII decimal [65-90])
            if (code > 96 && code < 123)
                code = code - 32;
            //robot.delay(40);
            robot.keyPress(code);
            robot.keyRelease(code);
        }
    }

    static void hit(int i) {
        robot.keyPress(i);
        robot.keyRelease(i);
    }

    static void combination(int... i) {
        for (int a : i) {
            robot.keyPress(a);
        }
        for (int a : i) {
            robot.keyRelease(a);
        }
    }

    static void paste(String s) {
        Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new StringSelection(s), null);
        combination(VK_CONTROL, VK_V);

    }

    static void paste(String s, int delay) {//delay is additional delay after auto robot delay
        String[] letters = s.split("");
        for (String a : letters) {
            Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new StringSelection(a), null);
            combination(VK_CONTROL, VK_V);
            robot.delay(delay);
        }
    }

    static void pasteRestore(String s) {
        Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
        Transferable save = clipboard.getContents(null);
        clipboard.setContents(new StringSelection(s), null);
        combination(VK_CONTROL, VK_V);
        clipboard.setContents(save, null);

    }

    static void pasteRestore(String s, int delay) {
        Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
        Transferable save = clipboard.getContents(null);

        String[] letters = s.split("");
        for (String a : letters) {
            clipboard.setContents(new StringSelection(a), null);
            combination(VK_CONTROL, VK_V);
        }
        clipboard.setContents(save, null);

    }




}

【问题讨论】:

  • 如果没有应用程序窗口处于活动状态,ALT F4 将关闭窗口。
  • @assylias 有道理,但是什么会使记事本窗口失去焦点?
  • 也许您错误地发送了错误的键码,例如 ALT-TAB。删除/注释掉 ALT-F4 和它之后的所有内容,并在按键之间添加延迟(以便于测试),然后运行它,看看它做了什么。
  • 另外,catch(Exception e) {} 是纯粹的邪恶。
  • @immibis 我按照你说的做了,似乎是随机的,不是很常见,记事本窗口没有获得焦点并出现在后台。这是非常奇怪的行为。不过感谢您的帮助!如果可以的话,我会将评论标记为“最佳答案”,但我不能:/

标签: java automation shutdown awtrobot


【解决方案1】:

我猜这个错误在方法combination() 中。再看一遍:

static void combination(int... i) {
    for (int a : i) {
        robot.keyPress(a);
    }
    for (int a : i) {
        robot.keyRelease(a);
    }
}

当按下 Alt-f4 时,用户应该会

  1. 按 Alt,
  2. 按 F4
  3. 释放 F4
  4. 释放 Alt。

在您的情况下,发布的顺序与印刷机的顺序相同。所以,我会尝试重写这个方法如下:

static void combination(int... c) {
    for (int a : c) {
        robot.keyPress(a);
    }
    for (int i = c.length - 1; i >=0; i--) {
        robot.keyRelease(c[i]);
    }
}

试试看。我希望这会奏效。

另外注意以下几行:

robot.setAutoDelay(30);
robot.setAutoWaitForIdle(true);

我个人从未使用过这些设置器。试着在没有他们的情况下工作。根据我在关闭窗口时的经验,你真的不需要延迟。一切都没有延迟,甚至更快。重点是您生成的事件的正确顺序。

【讨论】:

  • 正如@assylias 上面解释的那样,由于缺少窗口焦点,Alt-F4 命令是关闭计算机的原因。您是否认为按我所做的顺序按下组合键会导致某种窗口失焦?我不确定,因为网络上的所有其他组合键示例以及本网站都按照我按下它们的顺序显示它们。如果确实有影响,为什么第一个组合键可以正常工作?
  • 是的,我确实这么认为。试试吧,我很高兴知道你会得到什么。
  • 对不起,如果我的上述评论听起来像是防御性的。现在重读,这听起来有点刻薄和挑战你,这根本不是我的本意。无论如何,我试过了,由于我上面在记事本窗口主线程的 cmets 中描述的这个问题,很难说出来,有时不会立即获得焦点,但我认为它也许有帮助,因此我将此答案标记为已接受。我意识到一开始使用自动 Alt-F4 可能不是一个好主意。
  • 好吧,祝你好运。我真的希望它会有所帮助。至少我总是使用这种方法(我的意思是按相反的顺序释放键),因为它对我来说听起来更正确。
猜你喜欢
  • 2012-08-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-14
  • 2013-07-28
  • 1970-01-01
相关资源
最近更新 更多