Jump to content

Capturing screenshots while computer is locked


Recommended Posts

Hi folks, I'm having problems with a screenshot capture script.

Let me explain.

Everyday I (and my colleagues at work) need to take some screenshots from a web-page. These screenshots are used to compile a report. Normally, I (and others) used to log in into the website and took screenshots of desired graphics and tables. This is tediuos and time consuming. To easy this task I made a script using autoit that basically logs into the website (user and password) and using some clicks, stroke send, coordinates, it is able to generate the graphics and save them to some folders into our network (this script saves arouund 50 pics. It works like a sharm.

In order to make things easier, I tried to schedule this script (compiled to a Screnpics.exe file) using task scheduler from windows. We already use this (task scheduler) to run some vbs scripts, some vba excel scripts and so on. The computer used for this tasks is a windows 7 desktop computer. Due to security policies, the computer locks after some time. All this tasks run in the locked computer.

My script screenpics.exe runs also from this locked computer. When the computer is unlocked, it does everything as expected. But, when it is locked, all the "pics" are BLACK. As I understand, it runs ok, but, as the "windows" are innactive, it prints what it "sees": a black rectangular.

Some details: The web-page with hold the information I need, it only works in Firefox and, because of this it couldn`t be managed by vba or some "getobject" like commands. In fact, it has some flash things that make it impossible to control programatically. So my script is based on mouse move to coordinates, mouse click, screen capture and so one.

 

So, I read many posts trying to figure out a way to overcome this, but... nothing came to mind. My first idea was try to unlock windows. Theses lead me to some posts with no solution. This is worse because I'm not a computer admin, so procedures that need to replace/change the register are not an option.

 

If someone has any idea, I'll be gratefull.

Link to comment
Share on other sites

Hi @ammaul,

As I've understand with your issue is that when the computer exceeds the time limit, it will automatically locked the computer and your program won't work doing some screen capture.... well, as suggested with some other language, you can use the Anti Locking System coded in VB script and possible for Autoit codes, however, this system will unfortunately will not be locked unless the user will locked the computer. If you want it that way, then maybe I can help you.^_^

Programming is "To make it so simple that there are obviously no deficiencies" or "To make it so complicated that there are no obvious deficiencies" by C.A.R. Hoare.

Link to comment
Share on other sites

... or you can try with this modified version of the _ScreenCapture_CaptureWnd() function ...

#include <ScreenCapture.au3>
#include <WinAPISys.au3> ; used only for _WinAPI_LockWorkStation()

_Example()

Func _Example()
    ; run Calc
    Local $hPid = Run(@SystemDir & '\calc.exe')

    ; get calc's handle
    Local $hWnd = WinWaitActive("[CLASS:CalcFrame]", '', 3)

    If Not $hWnd Then
        MsgBox(0, "Not handle", "Problem with calc.exe")
        Exit
    EndIf

    ; Lock screen
    _WinAPI_LockWorkStation()

    Sleep(3000) ; wait a bit

    ; save the calc.exe screenshot to file calc.jpg
    ; even while the screen is locked
    _ScreenCapture_CaptureWnd_mod(".\Calc.jpg", $hWnd)

    ; close calc.exe
    ProcessClose($hPid)

    ; view the sceenshot
    ShellExecute(".\Calc.jpg")

EndFunc   ;==>_Example


; #FUNCTION# ====================================================================================================================
; Author ........: Paul Campbell (PaulIA)
; Modified.......: chimp
;
; modified version of the _ScreenCapture_CaptureWnd() function
; It uses the _WinAPI_PrintWindow() to capture the window
; ===============================================================================================================================
Func _ScreenCapture_CaptureWnd_mod($sFileName, $hWin, $bCursor = True)
    Local $bRet = False

    Local $iSize = WinGetPos($hWin)

    Local $iW = $iSize[2]
    Local $iH = $iSize[3]
    Local $hWnd = _WinAPI_GetDesktopWindow()
    Local $hDDC = _WinAPI_GetDC($hWnd)
    Local $hCDC = _WinAPI_CreateCompatibleDC($hDDC)
    Local $hBMP = _WinAPI_CreateCompatibleBitmap($hDDC, $iW, $iH)

    ; $hCDC Identifies the device context
    ; $hBMP Identifies the object to be selected
    _WinAPI_SelectObject($hCDC, $hBMP)
    _WinAPI_PrintWindow($hWin, $hCDC)

    If $bCursor Then
        Local $aCursor = _WinAPI_GetCursorInfo()
        If Not @error And $aCursor[1] Then
            $bCursor = True ; Cursor info was found.
            Local $hIcon = _WinAPI_CopyIcon($aCursor[2])
            Local $aIcon = _WinAPI_GetIconInfo($hIcon)
            If Not @error Then
                _WinAPI_DeleteObject($aIcon[4]) ; delete bitmap mask return by _WinAPI_GetIconInfo()
                If $aIcon[5] <> 0 Then _WinAPI_DeleteObject($aIcon[5]); delete bitmap hbmColor return by _WinAPI_GetIconInfo()
                _WinAPI_DrawIcon($hCDC, $aCursor[3] - $aIcon[2] - $iSize[0], $aCursor[4] - $aIcon[3] - $iSize[1], $hIcon)
            EndIf
            _WinAPI_DestroyIcon($hIcon)
        EndIf
    EndIf

    _WinAPI_ReleaseDC($hWnd, $hDDC)
    _WinAPI_DeleteDC($hCDC)
    If $sFileName = "" Then Return $hBMP

    $bRet = _ScreenCapture_SaveImage($sFileName, $hBMP, True)
    Return SetError(@error, @extended, $bRet)
EndFunc   ;==>_ScreenCapture_CaptureWnd_mod

 

 

image.jpeg.9f1a974c98e9f77d824b358729b089b0.jpeg Chimp

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Link to comment
Share on other sites

KickStarter15,

Hi, when the computer is locked, it runs ok (I scheduled it through task scheduler for 7:30 AM), but the snapshots are "black pics/black rectangles". 

Using codes to avoid computer locking is not an option, since this computer will became available to everyone (other users), and they could, using my user and password (because the computer will be open) acess some restricted folders/programs/information.

Cause of this, I need to unlock the computer and run and lock again, OR, correct the issue of saving "black snapshots". 

Thanks.

 

Chimp,

I´m using:

#include <ScreenCapture.au3>
_ScreenCapture_Capture ( [$sFileName = "" [, $iLeft = 0 [, $iTop = 0 [, $iRight = -1 [, $iBottom = -1 [, $bCursor = True]]]]]] )

You suggested:

#include <ScreenCapture.au3>
_ScreenCapture_CaptureWnd ( $sFileName, $hWnd [, $iLeft = 0 [, $iTop = 0 [, $iRight = -1 [, $iBottom = -1 [, $bCursor = True]]]]] )

Whats the difference? I couldn't find a handler for the window I need to "capture".

See below a screenshot of the webpage I´m trying to capture: Table 1 - I need do capture the table itself.. Table 2: I need to capture the "pop-up" chart.

This is the code to capture pop-up from Table2.

Sleep(1000)
MouseClick("left",464,476,1)
Sleep(3000)
_ScreenCapture_Capture ( $networkSharePath & "\peo_craq_rpbc_top10_alarmop.png", 282, 175, 1062, 640)
Sleep(1000)
MouseClick("left",1055,127,1)
Sleep(100)
Send("{CTRLDOWN}w{CTRLUP}")

Thanks.

 

Table1.png

Table2.png

Link to comment
Share on other sites

... to grab data from web tables there are more appropriate ways than capturing screens, but that's another story.
however, keeping the topic on the capture of the FireFox screenshots, you could try the following way:

#include <ScreenCapture.au3>
#include <WinAPISys.au3> ; used only for _WinAPI_LockWorkStation()

_Example()

Func _Example()

    ; MozillaWindowClass
    Local $aList = WinList("[CLASS:MozillaWindowClass]"), $hHandle

    ; get FirFox handle
    For $i = 1 To $aList[0][0]
        If $aList[$i][0] <> "" And BitAND(WinGetState($aList[$i][1]), 2) Then
            $hHandle = $aList[$i][1]
            ExitLoop
        EndIf
    Next

    If Not $hHandle Then
        MsgBox(0, "Not handle", "Problem with mozilla")
        Exit
    EndIf

    ; Activate the firefox window and maximize it
    WinActivate($hHandle)
    WinSetState($hHandle, '', @SW_MAXIMIZE)

    ; Lock screen (just to test)
    _WinAPI_LockWorkStation()

    Sleep(3000) ; wait a bit

    ; save the cscreenshot to file Moz.jpg
    ; even while the screen is locked
    _ScreenCapture_CaptureWnd_mod(".\Moz.jpg", $hHandle)

    ; view the sceenshot
    ShellExecute(".\Moz.jpg")

EndFunc   ;==>_Example


; #FUNCTION# ====================================================================================================================
; Author ........: Paul Campbell (PaulIA)
; Modified.......: chimp
;
; modified version of the _ScreenCapture_CaptureWnd() function
; It uses the _WinAPI_PrintWindow() to capture the window
; ===============================================================================================================================
Func _ScreenCapture_CaptureWnd_mod($sFileName, $hWin, $bCursor = True)
    Local $bRet = False

    Local $iSize = WinGetPos($hWin)

    Local $iW = $iSize[2]
    Local $iH = $iSize[3]
    Local $hWnd = _WinAPI_GetDesktopWindow()
    Local $hDDC = _WinAPI_GetDC($hWnd)
    Local $hCDC = _WinAPI_CreateCompatibleDC($hDDC)
    Local $hBMP = _WinAPI_CreateCompatibleBitmap($hDDC, $iW, $iH)

    ; $hCDC Identifies the device context
    ; $hBMP Identifies the object to be selected
    _WinAPI_SelectObject($hCDC, $hBMP)
    _WinAPI_PrintWindow($hWin, $hCDC)

    If $bCursor Then
        Local $aCursor = _WinAPI_GetCursorInfo()
        If Not @error And $aCursor[1] Then
            $bCursor = True ; Cursor info was found.
            Local $hIcon = _WinAPI_CopyIcon($aCursor[2])
            Local $aIcon = _WinAPI_GetIconInfo($hIcon)
            If Not @error Then
                _WinAPI_DeleteObject($aIcon[4]) ; delete bitmap mask return by _WinAPI_GetIconInfo()
                If $aIcon[5] <> 0 Then _WinAPI_DeleteObject($aIcon[5]); delete bitmap hbmColor return by _WinAPI_GetIconInfo()
                _WinAPI_DrawIcon($hCDC, $aCursor[3] - $aIcon[2] - $iSize[0], $aCursor[4] - $aIcon[3] - $iSize[1], $hIcon)
            EndIf
            _WinAPI_DestroyIcon($hIcon)
        EndIf
    EndIf

    _WinAPI_ReleaseDC($hWnd, $hDDC)
    _WinAPI_DeleteDC($hCDC)
    If $sFileName = "" Then Return $hBMP

    $bRet = _ScreenCapture_SaveImage($sFileName, $hBMP, True)
    Return SetError(@error, @extended, $bRet)
EndFunc   ;==>_ScreenCapture_CaptureWnd_mod
Edited by Chimp

 

image.jpeg.9f1a974c98e9f77d824b358729b089b0.jpeg Chimp

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Link to comment
Share on other sites

Sorry for my lack of knowlodge. How should I use this func_Example. I tried to run it but commands are grey (not available).

To explain a little. What we need are the pictures (not necessarily the data from the tables/graphics).

Thanks.

Link to comment
Share on other sites

17 hours ago, ammaul said:

.... How should I use this ...

  1. copy the following script (3 functions) and paste it to the bottom of your already working script (ensure that #include <ScreenCapture.au3> is present at the top of your script)
  2. to capture the screenshot of the FireFox window replace the line in your script where you call _ScreenCapture_Capture ( $networkSharePath & "\peo_craq_rpbc_top10_alarmop.png", 282, 175, 1062, 640) with the following line instead: _CaptureFireFox_Screen($sFilename) wher $sFilename contains the path and filename of the picture you wish to save. This should save a picture of the FireFox window on the path and with the name specified in the $sFilename parameter even if the screen is locked (it works on my system).
; #include <ScreenCapture.au3>

Func _CaptureFireFox_Screen($sFilename)

    $hFFox = HWnd(_Firefox_Get_Handle())
    If @error Then Return SetError(1, 0, False)

    ; save the screenshot of the FireFox window to $sFilename
    ; even while the screen is locked
    _ScreenCapture_CaptureWnd_mod($sFilename, $hFFox)
EndFunc   ;==>_CaptureFireFox_Screen

; retrieve the handle of FireFox (and maximize it)
Func _Firefox_Get_Handle()

    ; MozillaWindowClass
    Local $aList = WinList("[CLASS:MozillaWindowClass]"), $hHandle

    ; get FirFox handle
    For $i = 1 To $aList[0][0]
        If $aList[$i][0] <> "" And BitAND(WinGetState($aList[$i][1]), 2) Then
            $hHandle = $aList[$i][1]
            ExitLoop
        EndIf
    Next

    If Not $hHandle Then
        ; MsgBox(0, "Debug", "Problem on getting FireFox handle")
        Return SetError(1, 0, False)
    EndIf

    ; Activate the firefox window and maximize it
    WinActivate($hHandle)
    WinSetState($hHandle, '', @SW_MAXIMIZE)

    Return $hHandle
EndFunc   ;==>_Firefox_Get_Handle


; #FUNCTION# ====================================================================================================================
; Author ........: Paul Campbell (PaulIA)
; Modified.......: chimp
;
; modified version of the _ScreenCapture_CaptureWnd() function
; It uses the _WinAPI_PrintWindow() to capture the window
; it should work also with screen locked
;                          -------------
; ===============================================================================================================================
Func _ScreenCapture_CaptureWnd_mod($sFilename, $hWin, $bCursor = True)
    Local $bRet = False

    Local $iSize = WinGetPos($hWin)

    Local $iW = $iSize[2]
    Local $iH = $iSize[3]
    Local $hWnd = _WinAPI_GetDesktopWindow()
    Local $hDDC = _WinAPI_GetDC($hWnd)
    Local $hCDC = _WinAPI_CreateCompatibleDC($hDDC)
    Local $hBMP = _WinAPI_CreateCompatibleBitmap($hDDC, $iW, $iH)

    ; $hCDC Identifies the device context
    ; $hBMP Identifies the object to be selected
    _WinAPI_SelectObject($hCDC, $hBMP)
    _WinAPI_PrintWindow($hWin, $hCDC)

    If $bCursor Then
        Local $aCursor = _WinAPI_GetCursorInfo()
        If Not @error And $aCursor[1] Then
            $bCursor = True ; Cursor info was found.
            Local $hIcon = _WinAPI_CopyIcon($aCursor[2])
            Local $aIcon = _WinAPI_GetIconInfo($hIcon)
            If Not @error Then
                _WinAPI_DeleteObject($aIcon[4]) ; delete bitmap mask return by _WinAPI_GetIconInfo()
                If $aIcon[5] <> 0 Then _WinAPI_DeleteObject($aIcon[5]) ; delete bitmap hbmColor return by _WinAPI_GetIconInfo()
                _WinAPI_DrawIcon($hCDC, $aCursor[3] - $aIcon[2] - $iSize[0], $aCursor[4] - $aIcon[3] - $iSize[1], $hIcon)
            EndIf
            _WinAPI_DestroyIcon($hIcon)
        EndIf
    EndIf

    _WinAPI_ReleaseDC($hWnd, $hDDC)
    _WinAPI_DeleteDC($hCDC)
    If $sFilename = "" Then Return $hBMP

    $bRet = _ScreenCapture_SaveImage($sFilename, $hBMP, True)
    Return SetError(@error, @extended, $bRet)
EndFunc   ;==>_ScreenCapture_CaptureWnd_mod

 

 

image.jpeg.9f1a974c98e9f77d824b358729b089b0.jpeg Chimp

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Link to comment
Share on other sites

  • 2 weeks later...

Hi Chimp,

Sorry for the delay. I tried what you proposed. First I reduced my code to just two snapshots. For the first I used your suggestion. For the second, I left as it was.

I used part of your Func example () and simulated the computer lock.

Both snapshots were created during lock time. Both were equally black, unfortunatelly.

Please see code attached.

 

Any other ideas.

peo_craq_recap_top10_alarmop.png

peo_craq_rpbc_top10_alarmop.png

BR-Alarm.au3

Link to comment
Share on other sites

Are you sure that the issue is because the computer is locked?  I just ran a test on a Windows 7 box and my script successfully captured the specified window while the computer was sitting at the login screen.

I think your issue may be that a screen screen saver is running, your power settings are set to power down the monitor after a certain amount of idle time, or both,  Can you check to see if you have a screen saver enabled and/or whether your power settings are set to shut off the monitor?  If the power settings are shutting off the monitor, I have a solution for that.

Edited by TheXman
Link to comment
Share on other sites

  • 3 weeks later...

I XMan,

I dont think this is the issue, cause I forced the computer into lock mode using _WinAPI_LockWorkStation ( ) and then took the two snaphots above.

But I ckecked power setting and the monitor is turned off 10 minutes after locking the computer. I changed it to never turn off the monitor. Lets try again tomorrow morning.

 

Link to comment
Share on other sites

  • 2 weeks later...

Hey,

Try this function (not mine, found it sometime ago and changed a bit of it), it should take a screenshot of any window even when the computer is locked:

 

#include <GDIPlus.au3>
#include <WinAPISysWin.au3>

Capture_Window("test window",@DesktopDir&"\Test.png")

Func Capture_Window($Title, $SaveImagePath)
    WinSetState($Title, "", @SW_MAXIMIZE)
    Local $hWnd = WinGetHandle($Title)
    Local $w = _WinAPI_GetWindowWidth($hWnd)
    Local $h = _WinAPI_GetWindowHeight($hWnd)

    _GDIPlus_Startup()

    If Not IsHWnd($hWnd) Then Return SetError(1, 0, 0)
    If Int($w) < 1 Then Return SetError(2, 0, 0)
    If Int($h) < 1 Then Return SetError(3, 0, 0)
    Local Const $hDC_Capture = _WinAPI_GetDC(HWnd($hWnd))
    Local Const $hMemDC = _WinAPI_CreateCompatibleDC($hDC_Capture)
    Local Const $hHBitmap = _WinAPI_CreateCompatibleBitmap($hDC_Capture, $w, $h)
    Local Const $hObjectOld = _WinAPI_SelectObject($hMemDC, $hHBitmap)
    DllCall("gdi32.dll", "int", "SetStretchBltMode", "hwnd", $hDC_Capture, "uint", 4)
    DllCall("user32.dll", "int", "PrintWindow", "hwnd", $hWnd, "handle", $hMemDC, "int", 0)

    _WinAPI_DeleteDC($hMemDC)
    _WinAPI_SelectObject($hMemDC, $hObjectOld)
    _WinAPI_ReleaseDC($hWnd, $hDC_Capture)

    Local Const $hFullScreen = WinGetHandle("[TITLE:Program Manager;CLASS:Progman]")
    Local Const $aFullScreen = WinGetPos($hFullScreen)
    Local Const $c1 = $aFullScreen[2] - @DesktopWidth, $c2 = $aFullScreen[3] - @DesktopHeight
    Local Const $wc1 = $w - $c1, $hc2 = $h - $c2

    If (($wc1 > 1 And $wc1 < $w) Or ($w - @DesktopWidth > 1) Or ($hc2 > 7 And $hc2 < $h) Or ($h - @DesktopHeight > 1)) And (BitAND(WinGetState(HWnd($hWnd)), 32) = 32) Then
        Local $hBmp_t = _GDIPlus_BitmapCreateFromHBITMAP($hHBitmap)
        $hBmp = _GDIPlus_BitmapCloneArea($hBmp_t, 8, 8, $w - 16, $h - 16)
        _GDIPlus_BitmapDispose($hBmp_t)
    Else
        $hBmp = _GDIPlus_BitmapCreateFromHBITMAP($hHBitmap)
    EndIf
    _WinAPI_DeleteObject($hHBitmap)

    $hBmp = _GDIPlus_BitmapCloneArea($hBmp, 0, 0, $w - 16, $h - 16)

    _GDIPlus_ImageSaveToFile($hBmp, $SaveImagePath)
    _GDIPlus_Shutdown()
    Return $hBmp
EndFunc   ;==>Capture_Window

 

Link to comment
Share on other sites

  • 4 months later...

I recently had the same issue where screen captures of web pages would render as blank/black pages when using _ScreenCapture_CaptureWnd().  What fixed the issue for me was disabling graphics acceleration in the browser's settings.

Edited by TheXman
Link to comment
Share on other sites

Does something that reset the screensaver / lock screen timer is a solution for you ?

I find back that one for you if the answer is YES :) 

 

Edited by caramen

My video tutorials : ( In construction )  || My Discord : https://discord.gg/S9AnwHw

How to Ask Help ||  UIAutomation From Junkew || WebDriver From Danp2 || And Water's UDFs in the Quote

Spoiler

 Water's UDFs:
Active Directory (NEW 2018-10-19 - Version 1.4.10.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (2018-10-31 - Version 1.3.4.1) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
PowerPoint (2017-06-06 - Version 0.0.5.0) - Download - General Help & Support
Excel - Example Scripts - Wiki
Word - Wiki
 
Tutorials:

ADO - Wiki

 

Link to comment
Share on other sites

  • 5 years later...

Hi everyone

I have been using the _ScreenCapture_CaptureWnd_mod for years and I want to thank the developer for creating it.💖🙏

However, I now need to take a screenshot of the entire desktop, not just a window. (Whatever windows are open + taskbar) I have tried researching and experimenting with different methods, but have not had any success.

⁉️ Can anyone guide how to use this function, or suggest another method to take a screenshot of the entire desktop while Windows is in lock mode?

Cheers

IgImAx

Edited by IgImAx
extra info

Teach Others to learn more yourself

My eBooks and Articles in Persian: IgImAx Home! * and more here

Link to comment
Share on other sites

..the canvas shows the locked screen. That's pretty much that.

unless https://www.autoitscript.com/forum/topic/194120-capturing-screenshots-while-computer-is-locked/?do=findComment&comment=1397338 works ?

Edited by argumentum

Follow the link to my code contribution ( and other things too ).
FAQ - Please Read Before Posting.
autoit_scripter_blue_userbar.png

Link to comment
Share on other sites

Not sure if it is possible.  PrintWindow requires to accept the message WM_PRINT.  Pretty confident that Desktop will not respond to it.  So at the end of the day, you need to ask yourself what you really need to know.  And choose how you can securely get this information without a human looking at it....

Another option (beside locking the PC) is to lock total input (keyboard and mouse : look at my signature for it).  Then you can do pretty much all you want !

ps. there is ways to shutdown the screen but PrintWindow will still work if the PC is not locked (it will not work will all monitors since some always research if there is a possible input from HDMI, VGA, etc).  But with a black screen without any possible input, it is quite secure...On the other hand you will need to kill the process to gain access to your PC again.

Edited by Nine
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...