Что нового

[Автоматизация] Скриншот клиент-серверный скрипт

const_var

Новичок
Сообщения
1
Репутация
0
Версия AutoIt: 3.3.8.1

Описание: Программа должна делать скриншот в файл на сетевой ресурс или в локальную папку (но не в папку со скриптом) по сигналу на определенный порт с другой машины.

Примечания:
Нашел релевантные темы, вот исходники с них:
Это про то как сделать снимок всего экрана:
Код:
#Include <ClipBoard.au3>
#Include <GDIPlus.au3>

$sFile = @DesktopDir & '\Screenshot.bmp'

_ScreenCapture($sFile, True)
ShellExecute($sFile)

Func _ScreenCapture($sFile, $bActiveWindow = 0)
    Local $Result, $Timer, $Old_Clip, $hImage, $hBitmap = 0
    $Old_Clip = ClipGet()
    ClipPut('')
    If $bActiveWindow Then
        Send('!{PRINTSCREEN}')
    Else
        Send('{PRINTSCREEN}')
    EndIf
    $Timer = TimerInit()
    While TimerDiff($Timer) < 1000
        _ClipBoard_Open(0)
        $hBitmap = _ClipBoard_GetDataEx($CF_BITMAP)
        _ClipBoard_Close()
        If $hBitmap Then
            ExitLoop
        EndIf
        Sleep(10)
    WEnd
    If Not $hBitmap Then
        ClipPut($Old_Clip)
        Return 0
    EndIf
    _GDIPlus_Startup()
    $hImage = _GDIPlus_BitmapCreateFromHBITMAP($hBitmap)
    $Result = _GDIPlus_ImageSaveToFile($hImage, $sFile)
    _GDIPlus_ImageDispose($hImage)
    _GDIPlus_Shutdown()
    ClipPut($Old_Clip)
    Return $Result
EndFunc   ;==>_ScreenCapture

Вот это то же, но для Windows 7 / Aero
Код:
#Include <ClipBoard.au3>
#Include <GDIPlus.au3>

$sFile = @DesktopDir & '\Screenshot.bmp'

_ScreenCapture($sFile, True)
ShellExecute($sFile)

Func _ScreenCapture($sFile, $bActiveWindow = 0)
    Local $Result, $Timer, $Old_Clip, $hImage, $hBitmap = 0
    $Old_Clip = ClipGet()
    ClipPut('')
    If $bActiveWindow Then
        Send('!{PRINTSCREEN}')
    Else
        Send('{PRINTSCREEN}')
    EndIf
    $Timer = TimerInit()
    While TimerDiff($Timer) < 1000
        _ClipBoard_Open(0)
        $hBitmap = _ClipBoard_GetDataEx($CF_BITMAP)
        _ClipBoard_Close()
        If $hBitmap Then
            ExitLoop
        EndIf
        Sleep(10)
    WEnd
    If Not $hBitmap Then
        ClipPut($Old_Clip)
        Return 0
    EndIf
    _GDIPlus_Startup()
    $hImage = _GDIPlus_BitmapCreateFromHBITMAP($hBitmap)
    $Result = _GDIPlus_ImageSaveToFile($hImage, $sFile)
    _GDIPlus_ImageDispose($hImage)
    _GDIPlus_Shutdown()
    ClipPut($Old_Clip)
    Return $Result
EndFunc   ;==>_ScreenCapture


Клиент-серверная версия с передачей картинки на клиент (напоминаю, что мне нужно, чтобы сервер просто сохранил скриншот, а не передавал его)
Клиентская часть:

Код:
#Include <GDIPlus.au3>
#Include <Memory.au3>
#Include <WinAPIEx.au3>

TCPStartup()
$Socket = TCPConnect(@IPAddress1, 33891)
If @error Then
    Exit
EndIf

_GDIPlus_Startup()

Global $tEncoder = _WinAPI_GUIDFromString(_GDIPlus_EncodersGetCLSID('png'))
Global $pEncoder = DllStructGetPtr($tEncoder)

While 1
    TCPSend($Socket, _GetScreenshot(0, 0, 800, 600))
    If @error Then
        ExitLoop
    EndIf
    Sleep(1000)
WEnd

_GDIPlus_Shutdown()

TCPShutdown()

Func _GetScreenshot($iX = 0, $iY = 0, $iWidth = -1, $iHeight = -1)

    Local $hSrcDC, $hDstDC, $hDstSv, $hBitmap, $hDesktop, $hScreen, $hMemory, $pMemory, $pStream, $tOut, $pOut, $iSize

    If $iWidth = -1 Then
        $iWidth = @DesktopWidth
    EndIf
    If $iHeight = -1 Then
        $iHeight = @DesktopHeight
    EndIf
    $hDesktop = _WinAPI_GetDesktopWindow()
    $hSrcDC = _WinAPI_GetDC($hDesktop)
    $hScreen = _WinAPI_CreateCompatibleBitmap($hSrcDC, $iWidth, $iHeight)
    $hDstDC = _WinAPI_CreateCompatibleDC($hSrcDC)
    $hDstSv = _WinAPI_SelectObject($hDstDC, $hScreen)
    _WinAPI_BitBlt($hDstDC, $iX, $iY, $iWidth, $iHeight, $hSrcDC, $iX, $iY, $SRCCOPY)
    _WinAPI_SelectObject($hDstDC, $hDstSv)
    _WinAPI_ReleaseDC($hDesktop, $hSrcDC)
    _WinAPI_DeleteDC($hDstDC)
    $hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hScreen)
    _WinAPI_DeleteObject($hScreen)
    $pStream = _WinAPI_CreateStreamOnHGlobal(0)
    _GDIPlus_ImageSaveToStream($hBitmap, $pStream, $pEncoder)
    _GDIPlus_BitmapDispose($hBitmap)
    $hMemory = _WinAPI_GetHGlobalFromStream($pStream)
    $pMemory = _MemGlobalLock($hMemory)
    $iSize = _MemGlobalSize($hMemory)
    $tOut = DllStructCreate('dword;dword;byte[' & ($iSize - Mod($iSize, 4) + 4) & ']')
    $pOut = DllStructGetPtr($tOut)
    DllStructSetData($tOut, 1, DllStructGetSize($tOut))
    DllStructSetData($tOut, 2, $iSize)
    _MemMoveMemory($pMemory, $pOut + 8, $iSize)
    _MemGlobalFree($hMemory)
    Return DllStructGetData(DllStructCreate('byte[' & DllStructGetSize($tOut) & ']', DllStructGetPtr($tOut)), 1)
EndFunc   ;==>_GetScreenshot

Func _GDIPlus_ImageSaveToStream($hImage, $pStream, $pEncoder, $pParams = 0)

    Local $Ret = DllCall($ghGDIPDll, 'uint', 'GdipSaveImageToStream', 'ptr', $hImage, 'ptr', $pStream, 'ptr', $pEncoder, 'ptr', $pParams)

    If (@error) Or ($Ret[0]) Then
        Return SetError(@error, @extended, 0)
    EndIf
    Return 1
EndFunc   ;==>_GDIPlus_ImageSaveToStream


Серверная часть

Код:
#Include <Constants.au3>
#Include <GDIPlus.au3>
#Include <Memory.au3>
#Include <WinAPIEx.au3>

Global Const $STM_SETIMAGE = 0x0172
Global Const $STM_GETIMAGE = 0x0173

TCPStartup()
$Main = TCPListen(@IPAddress1, 33891)
If @error Then
    Exit
EndIf

GUICreate('MyGUI', 800, 600, @DesktopWidth - 819, @DesktopHeight - 671)
$Pic = GUICtrlCreatePic('', 0, 0, 800, 600)
GUISetState()

Do
    $Socket = TCPAccept($Main)
Until $Socket <> -1

Global $tHeader = DllStructCreate('byte[4]')
Global $pHeader = DllStructGetPtr($tHeader)
Global $bData = 0, $Count = 0

_GDIPlus_Startup()

Do
    If Not IsBinary($bData) Then
        $bData = TCPRecv($Socket, 16384, 1)
        If @error Then
            ExitLoop
        EndIf
    EndIf
    If IsBinary($bData) Then
        If Not $Count Then
            DllStructSetData($tHeader, 1, $bData)
            $tData = DllStructCreate('dword', $pHeader)
            $Size = DllStructGetData($tData, 1)
            $tData = DllStructCreate('byte[' & $Size & ']')
            $pData = DllStructGetPtr($tData)
        EndIf
        $Lenght = BinaryLen($bData)
        $Sum = $Count + $Lenght
        If $Sum > $Size Then
            $dL = $Size - $Count
            $tPart = DllStructCreate('byte[' & $dL & ']', $pData + $Count)
            DllStructSetData($tPart, 1, $bData)
            $tByte = DllStructCreate('byte[' & $Lenght & ']')
            $tRecv = DllStructCreate('byte[' & ($Lenght - $dL) & ']', DllStructGetPtr($tByte) + $dL)
            DllStructSetData($tByte, 1, $bData)
            $bData = DllStructGetData($tRecv, 1)
            $Sum = $Size
        Else
            $tPart = DllStructCreate('byte[' & $Lenght & ']', $pData + $Count)
            DllStructSetData($tPart, 1, $bData)
            $Count = $Sum
            $bData = 0
        EndIf
        If $Sum = $Size Then
            _SetScreenshot($Pic, $tData)
            $Count = 0
        EndIf
    EndIf
Until GUIGetMsg() = -3

_GDIPlus_Shutdown()

TCPCloseSocket($Socket)
TCPShutdown()

Func _SetScreenshot($CtrlID, ByRef $tData, $fUpdate = 0)

    Local $hBitmap, $hPrev, $hScreen, $hMemory, $pMemory, $pStream, $pData, $iSize

    $hWnd = GUICtrlGetHandle($CtrlID)
    If Not $hWnd Then
        Return 0
    EndIf

    $pData = DllStructGetPtr($tData)
    $iSize = DllStructGetData(DllStructCreate('dword', $pData + 4), 1)
    $hMemory = _MemGlobalAlloc($iSize, $GMEM_MOVEABLE)
    $pMemory = _MemGlobalLock($hMemory)
    _MemMoveMemory($pData + 8, $pMemory, $iSize)
    _MemGlobalUnlock($hMemory)
    $pStream = _WinAPI_CreateStreamOnHGlobal($hMemory)
    $hBitmap = _GDIPlus_BitmapCreateFromStream($pStream)
    $hScreen = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap)
    _GDIPlus_BitmapDispose($hBitmap)
    _MemGlobalFree($hMemory)
    _WinAPI_DeleteObject(_SendMessage($hWnd, $STM_SETIMAGE, $IMAGE_BITMAP, $hScreen))
    $hPrev = _SendMessage($hWnd, $STM_GETIMAGE)
    If $hPrev <> $hScreen Then
        _WinAPI_DeleteObject($hScreen)
    EndIf
    If $fUpdate Then
        _WinAPI_UpdateWindow($hWnd)
    EndIf
    Return 1
EndFunc   ;==>_SetScreenshot

Func _GDIPlus_BitmapCreateFromStream($pStream)

    Local $Ret = DllCall($ghGDIPDll, 'uint', 'GdipCreateBitmapFromStream', 'ptr', $pStream, 'ptr*', 0)

    If (@error) Or ($Ret[0]) Then
        Return SetError(@error, @extended, 0)
    EndIf
    Return $Ret[2]
EndFunc   ;==>_GDIPlus_BitmapCreateFromStream
 
Верх