简体   繁体   中英

Is it possible to programmatically take a screenshot while the computer is locked?

I am running Selenium testing overnight (using Java & WebDriver) and would like to take a screenshot when one of the testcases fails. If I use the Robot's createScreenCapture() method it only works if the monitor is on, and if I use the Selenium's getScreenshotAs() method it doesn't capture any popups or anything that are on top of the window (and often contain the cause of the problem). The getScreenshotAs() method does work when the pc is locked so that is what I am currently using. My machines run Windows 7 if that matters.

I adapted this code (found on this site) and am using this currently:

WebDriver driver = new FirefoxDriver();
driver.get("http://www.google.com/");
File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
// Now you can do whatever you need to do with it, for example copy somewhere
FileUtils.copyFile(scrFile, new File("c:\\tmp\\screenshot.png"));

This is what I had used previously but it only captures a grey screen with the task bar at the bottom if the pc is locked, but if I'm logged in it works great and captures everything. The problem is I need to have my computer locked overnight and that is when this code needs to run:

Robot robot = new Robot();
// Get size of screen
Rectangle screenRect = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize());
// Capture the screen
BufferedImage screenFullImage = robot.createScreenCapture(screenRect);
// Save the screen to to disk
ImageIO.write(screenFullImage, "jpg", new File(fileName));

I found some other posts on here asking similar questions but they were all pretty old and didn't quite match my question so I was wondering if any solution given these circumstances was possible?


EDIT: When I use the Robot code these are the results. I tried using both Chrome as the browser (ChromeDriver) and Firefox (FirefoxDriver).

Chrome: 截图使用谷歌浏览器

Firefox: 在此输入图像描述

If I run the Robot version of the screen capture in a class all by itself, just a loop that captures the screen every 5 seconds (Run As > Java Application), it works just fine even with the computer locked, but when I have Selenium run the same code (its Run As > JUnit Test) when a test fails it gives the screenshots above if the pc is locked. I even tried having the Selenium code spawn a new thread to take the screenshot while it did a Thread.sleep() but got the same results once the pc was locked.

On a personal desktop, locking screen should not be an issue in capturing screen using AWT Robot.

You can test it using the script ScreenCapture.java

  • Download the java file on to a folder.
  • Open cmd in the folder where the file in downloaded
  • javac ScreenCapture.java
  • java ScreenCapture

You should be seeing the screenshots getting captured in a loop in the folder. Lock the screen, wait for 5 seconds and then unlock the screen and check the screenshots

In case of a virtual machine or a remote computer which is accessed via RDP, locking can result in black screenshots.

When a user accesses a desktop normally (without RDP as in case of a laptop or personal computer), user session is set to console. You can see it using the below command.

c:\Users\*******\Desktop>query user
USERNAME              SESSIONNAME        ID  STATE   IDLE TIME  LOGON TIME
>*********              console             1  Active      none   12/18/2018 5:50 PM 

You can see that the user is connected to the session console . In this mode the capture screenshot works perfectly.

But if you are accessing the Desktop using RDP you see the below result.

c:\Users\*******\Desktop>FOR /L %N IN () DO (query user
timeout 2)

 // When the screen is locked (RDP closed)
 USERNAME              SESSIONNAME        ID  STATE   IDLE TIME  LOGON TIME
>*********                                  1  Disc            .  8/21/2018 12:25 PM
 // When RDP session is active
 USERNAME              SESSIONNAME        ID  STATE   IDLE TIME  LOGON TIME
>*********              rdp-tcp#0           1  Active       none  8/21/2018 12:25 PM

You can see that when the RDP session is disconnected there is no session that is active. This results in the blank screenshot

Solution

When the RDP closes, you have to activate the console session using the below command. This can be done by setting up a scheduled task.

  1. Create a batch file with the below content.

     Tscon 1 /dest:console /v 
  2. Open task scheduler by opening Run and typing taskschd.msc
  3. In the Action menu , click Create Task
  4. Give a name to the task
  5. Select Run whether user is logged in or not check box
  6. In the Triggers tab, click New button
  7. Select On disconnect from user session and click OK
  8. In the Actions tab, click New button
  9. Action Start a program and point to the location of the batch file and click OK
  10. Click OK to create task

Sure, you can take screenshots when pc is locked using the browser -

public static String captureScreen(WebDriver driver, String screenName) throws IOException {
    String dest = null;
    try {
        Screenshot screenshot = new AShot().shootingStrategy(ShootingStrategies.viewportPasting(1000)).takeScreenshot(driver);
        dest = ScreenshotsPath() + "\\" + screenName + ".png";
        ImageIO.write(screenshot.getImage(), "PNG", new File(dest));
    } catch (Exception e) {
        e.printStackTrace(writeException.toFile());
    }
    return dest;
}

My method is returning destination(path to image) as a string because I'm using them in reports. I'm also using AShot() because i want to take a full page screenshot.

Thanks,

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM