AutoIT:从IE下载文件并将其保存在提到的目录

时间:2016-10-08 11:18:48

标签: selenium-webdriver automation autoit

我的要求是从Internet Explorer(版本11)下载文件并使用selenium和AutoIT将其保存到特定位置。保存文件的路径是通过命令行给出的。

这是我的代码:

; get the handle of main window
Local $windHandle= WinGetHandle("[Class:IEFrame]", "")
Local $winTitle = "[HANDLE:" & $windHandle & "]"

; Select save as option
WinActivate ($winTitle, "")
Send("{F6}")
sleep(500)
Send("{TAB}")
sleep(500)
Send("{DOWN}")
sleep(500)
Send("a")

; Save as dialog
; wait for Save As window
WinWait("Save As")
; activate Save As window
WinActivate("Save As")
ControlFocus("Save As","","Edit1")
ControlSetText("Save As","","Edit1",$CmdLine[1])
Sleep(2000)
ControlClick("Save As","","Button2")

===Execution of above code through selenium=====

Runtime.getRuntime().exec("D:\\AutoIT\\downloadFile.exe"+" "+"D:\\AutoIT\\abc.pdf");

它可以工作,但不会保存在特定文件中,而是保存在默认位置,即“另存为”窗口显示的位置。

请帮忙。

2 个答案:

答案 0 :(得分:0)

为什么你尝试使用不确定的Send()命令? AutoIt具有INetGet()函数来下载文件。我有时使用简单易用的下载功能和小GUI来显示进度,速度和剩余时间。可能对你有用:

#include <APIShellExConstants.au3>
#include <GuiStatusBar.au3>
#include <InetConstants.au3>
#include <ProgressConstants.au3>

; #FUNCTION# ====================================================================================================================
; Name ..........: _DownloadFile
; Description ...: Downloads a file from a given URL, shows: progress, speed and remaining time.
; Syntax ........: _DownloadFile($_sUrl, $_sFile[, $_sTitle = 'Download'[, $_iWidth = -1[, $_iHeight = -1[, $_iX = -1[, $_iY = -1]]]]])
; Parameters ....: $_sUrl               - The web adress of the file to load.
; ...............: $_sFile              - The path to store this file.
; ..[optional]...: $_sTitle             - Title of the download window. Default is '', = 'Download'.
; ..[optional]...: $_iWidth             - Width of the download window. Default is -1, = 250.
; ..[optional]...: $_iHeight            - Height of the download window. Default is -1, = 75.
; ..[optional]...: $_iX                 - X position of the download window. Default is -1, centered. Other negative value: X px from right, postive values: X px absolute.
; ..[optional]...: $_iY                 - Y position of the download window. Default is -1, centered. Other negative value: Y px from bottom, postive values: Y px absolute.
; Return values .: Success              None
; ...............: Failure              1 and show message box - download has failed or was escaped.
; Author ........: BugFix
; ===============================================================================================================================
Func _DownloadFile($_sUrl, $_sFile, $_sTitle='', $_iWidth=-1, $_iHeight=-1, $_iX=-1, $_iY=-1) ; Pos: -1/-1 = center, -X/-Y = X px from right / Y px from bottom
    $_sTitle = $_sTitle = '' ? 'Download' : $_sTitle
    $_iWidth = $_iWidth = -1 ? 250 : $_iWidth
    $_iHeight = $_iHeight = -1 ? 75 : $_iHeight
    If FileExists($_sFile) Then FileMove($_sFile, $_sFile & '.bak', 1)

    ; Download in background, wait until DL complete - show it in GUI
    Local $iBytesSize, $hDL = GUICreate($_sTitle, $_iWidth, $_iHeight, -1, -1, BitOR(0x00C00000,0x00080000)) ; WS_CAPTION,WS_SYSMENU
    Local $idDL_sum = GUICtrlCreateLabel('0,000 KB', 5, 5, $_iWidth-10, 30, 0x01) ; SS_CENTER
    GUICtrlSetFont(-1, 14, Default, Default, 'Verdana')
    Local $aParts[3] = [75,$_iWidth-75,-1]
    Local $hStatus = _GUICtrlStatusBar_Create($hDL, $aParts)
    _GUICtrlStatusBar_SetMinHeight($hStatus, 25)
    Local $idProgress = GUICtrlCreateProgress(0, $_iHeight-20-26, $_iWidth, 20, $PBS_SMOOTH)
    Local $iTimer = TimerInit()
    ; get absolute window size, move window
    Local $aWin = WinGetPos($hDL)
    Select
        Case $_iX = -1
            $_iX = (@DesktopWidth - $aWin[2]) / 2
        Case $_iX < -1
            $_iX = @DesktopWidth - ($aWin[2] - $_iX)
    EndSelect
    Select
        Case $_iY = -1
            $_iY = (@DesktopHeight - $aWin[3]) / 2
        Case $_iY < -1
            $_iY = @DesktopHeight - ($aWin[3] - $_iY)
    EndSelect
    WinMove($hDL, '', $_iX, $_iY)
    GUISetState()

    Local $iSizeSource = InetGetSize($_sUrl)
    Local $hDownload = InetGet($_sUrl, $_sFile, $INET_FORCERELOAD, $INET_DOWNLOADBACKGROUND)
    _GUICtrlStatusBar_SetText($hStatus, @TAB & _FormatByte($iSizeSource, '', False, 0), 2)

    Local $fEsc = False, $iDL_old = 0, $iDL_diff, $iTimeNeed
    Do
        If TimerDiff($iTimer) >= 1000 Then
            $iBytesSize = InetGetInfo($hDownload, $INET_DOWNLOADREAD)
            GUICtrlSetData($idDL_sum, StringReplace(_FormatByte($iBytesSize), '.', ','))
            GUICtrlSetData($idProgress, Int(($iBytesSize/$iSizeSource)*100))
            $iDL_diff = $iBytesSize - $iDL_old
            $iDL_old = $iBytesSize
            _GUICtrlStatusBar_SetText($hStatus, @TAB & _FormatByte($iDL_diff, '', False, '0') & '/s', 0)
            $iTimeNeed = ($iSizeSource - $iBytesSize) / $iDL_diff
            _GUICtrlStatusBar_SetText($hStatus, @TAB & _FormatSeconds($iTimeNeed), 1)
            $iTimer = TimerInit()
        EndIf
        If GUIGetMsg() = -3 Then
            $fEsc = True
            ExitLoop
        EndIf
    Until InetGetInfo($hDownload, $INET_DOWNLOADCOMPLETE)
    _GUICtrlStatusBar_SetText($hStatus, '', 0)
    _GUICtrlStatusBar_SetText($hStatus, '', 1)

    ; get info about DL file
    Local $aData = InetGetInfo($hDownload)
    If @error Or $fEsc Then
        FileDelete($_sFile)
        Local $sTmp = $fEsc ? 'escaped' : 'failed'
        GUICtrlSetData($idDL_sum, 'Download ' & $sTmp & '!')
        Return SetError(1,0,MsgBox(262192, 'Error', 'The Download has ' & $sTmp & '.'))
    Else
        GUICtrlSetData($idDL_sum, StringReplace(_FormatByte($iBytesSize), '.', ','))
        GUICtrlSetData($idProgress, 100)
        Sleep(500)
        GUICtrlSetData($idDL_sum, 'Download finished.')
    EndIf
    InetClose($hDownload)
    GUIDelete($hDL)
EndFunc  ;==>_DownloadFile


; #FUNCTION# ====================================================================================================================
; Name ..........: _FormatSeconds
; Description ...: Returns a given value of seconds in the format
; ...............:        <24h: "hh:mm:ss", >=24h: "x d / hh:mm:ss h"
; Syntax ........: _FormatSeconds($_sec)
; Parameters ....: $_sec                - The number of seconds.
; Return values .: The formatted string.
; Author ........: BugFix
; ===============================================================================================================================
Func _FormatSeconds($_sec)
    Return ( $_sec < 60 ? StringFormat('00:00:%02u', $_sec) : _
             $_sec < 60*60 ? StringFormat('00:%02u', Floor($_sec/60)) & ':' & _
                    StringFormat('%02u', Mod($_sec,60)) : _
             $_sec < 60*60*24 ? StringFormat('%02u', Floor($_sec/3600)) & ':' & _
                    StringFormat('%02u', Floor(Mod($_sec,3600)/60)) & ':' & _
                    StringFormat('%02u', Mod(Mod($_sec,3600),60)) : _
             ( $_sec = 86400 ? "24:00:00" : Floor($_sec/86400) & ' d / ' & _
                    StringFormat('%02u', Floor(Mod($_sec,86400)/3600)) & ':' & _
                    StringFormat('%02u', Floor(Mod(Mod($_sec,86400),3600)/60)) & ':' & _
                    StringFormat('%02u', Mod(Mod(Mod($_sec,86400),3600),60)) & ' h') )
EndFunc  ;==>_FormatSeconds

; #FUNCTION# ====================================================================================================================
; Name ..........: _FormatByte
; Description ...: Formats a given value of bytes with highest or given unit, optional as structure with all units
; Parameters ....: $_iByte    The value of bytes to format
; ...............: $_sUnit    (Default = '', unit of highest value) or count of given unit (TB, GB, MB, KB, Byte)
; ...............: $_fStruct  Returns a structure with .TB .GB .MB .KB .Byte (Default = False)
; ...............: $_sDigit   Number of decimal digits (Default = '3') as string!
; Return values .: The formatted string or the structure.
; Author ........: BugFix
; ===============================================================================================================================
Func _FormatByte($_iByte, $_sUnit='', $_fStruct=False, $_sDigit='3')
    Local Static $aByte[5][2] = [[0x10000000000],[0x40000000],[0x100000],[0x400],[0x1]]
    Local Static $tBytes = DllStructCreate('int TB;int GB;int MB;int KB;int Byte;')
    Local Static $aUnit[5] = ['TB','GB','MB','KB','Byte']
    Local $iModulo = $_iByte, $iHighest = 4
    For $i = 0 To 3
        $aByte[$i][1] = $iModulo >= $aByte[$i][0] ? Floor($iModulo/$aByte[$i][0]) : 0
        $iModulo = $aByte[$i][1] > 0 ? Mod($iModulo,$aByte[$i][0]) : $iModulo
        $iHighest = $aByte[$i][1] > 0 ? ($i < $iHighest ? $i : $iHighest) : $iHighest
    Next
    $aByte[4][1] = $iModulo
    If $_fStruct Then
        $tBytes.TB   = $aByte[0][1]
        $tBytes.GB   = $aByte[1][1]
        $tBytes.MB   = $aByte[2][1]
        $tBytes.KB   = $aByte[3][1]
        $tBytes.Byte = $aByte[4][1]
        Return $tBytes
    EndIf
    $_sUnit = StringInStr('TB GB MB KB Byte', $_sUnit) ? $_sUnit : ''
    $_sUnit = $_sUnit = '' ? $aUnit[$iHighest] : $_sUnit
    Local $iUserUnit = Floor(StringInStr('TB GB MB KB Byte', $_sUnit)/3)
    If Number($_sDigit) < 0 Then $_sDigit = '0'
    Local $sFormat = '%.' & $_sDigit & 'f %s'
    Return StringFormat($sFormat, $_iByte/$aByte[$iUserUnit][0], $aUnit[$iUserUnit])
EndFunc  ;==>_FormatByte

答案 1 :(得分:0)

  

它可以工作,但不会保存在特定文件中,而是保存在   默认位置,即“另存为”窗口显示的位置。

我花了一段时间,但最终为我的项目弄清楚了,希望有人可以从中受益。原来,文件夹路径的地址栏是(工具栏按钮和编辑框)的组合。我不知道实际的结构,但我想像的方式是;编辑框嵌套在ToolbarWindow32中。单击地址栏(ToolbarWindow32)手动输入自己的路径后,将激活编辑框。想象一下,ToolbarWindow32是父级,而Edit框是子级。有知识的人请对此有所了解。

这是一个工作示例,具有完成同一件事的不同方法。

    #include <GuiToolbar.au3>
    #Include <File.au3>


    TestChangeSaveAsAddress()

    Func TestChangeSaveAsAddress()

        Run('Notepad.exe')
        WinWaitActive('Untitled - Notepad')
        Send('new line.')
        Send('^s')


        Local $AddressPath = 'K:\_DOC\_TEXT'
        Local $aFileName = 'New File.txt'
        ClipPut($AddressPath)                    ;for  Option 1

        Local $SaveAsTitle = '[CLASS:#32770; TITLE:Save As]'


    # I.a

        ;get 'Save As' window handle
        Local $hWnd = WinWaitActive($SaveAsTitle, '&Save', 10)

    # I.b

        ;get Address Bar handle for $AddressPath
        Local $hTollbars = ControlGetHandle($hWnd, 'Address', '[CLASSNN:ToolbarWindow324]')


    # II - IMPORTANT: Address Bar must be infocus in order to activate Edit2 to set $AddressPath in step (IV)
           ;Option 2 or 3 is highly recommended


        # ;Option 1 - Select ToolbarWindow32 - Address Bar (work around -not recomended)
        #------------------------------------------------------------------------------
    ;~         ControlFocus($hTollbars, 'Address', '')
    ;~         ControlSend($hTollbars, 'Address', '','{SPACE}')
    ;~         Send('^v{ENTER}')

        # ;Option 2 - Select ToolbarWindow32 - Address Bar (same as Option 3)
        #-------------------------------------------------------------------
             ControlCommand($hTollbars, "Address", "", "SendCommandID", 1280)

        # ;Option 3 - Select ToolbarWindow32 - Address Bar (same as Option 2)
        #------------------------------------------------------------------------------------------
    ;~         ControlCommand($hWnd, "Address", "ToolbarWindow324", "SendCommandID", 1280)

        # ;Option 4 - Select ToolbarWindow32 - Address Bar (mouse pointer also relocated)
        #------------------------------------------------------------------------------------------
    ;~        _GUICtrlToolbar_ClickIndex($hTollbars, -1,'Left',True,1,0)

        # ;Option 5 - Select ToolbarWindow32 - Address Bar (this simulate as Run, NOT RunWait if your project required it - NOT Recommended)
        #------------------------------------------------------------------------------------------
    ;~      Run(@AutoItExe & ' /AutoIt3ExecuteLine "ControlCommand ( hwnd(' & $hWnd & '),'''', hwnd(' & $hTollbars & '), ''SendCommandID'', 1280 )"')


    # III
            ;check if path $AddressPath exists
            If Not FileExists($AddressPath) Then DirCreate($AddressPath)

    # IV
            ;set new path
            ControlSetText($hWnd, "Address", 'Edit2', $AddressPath)
    ;~         ControlFocus($hTollbars,'Address','')


    # V
            ;commit new Path
            ControlSend($hWnd, "Address", 'Edit2','{ENTER}')

    # VI
            ;set new file name
            ControlSetText($hWnd, "Namespace", "Edit1", $aFileName)
            ControlFocus($hWnd,'Namespace','Edit1')

    # VII
            ;allow manual keypress {SPACE} or {ENTER} to save/cancel
    ;~         ControlFocus($hWnd,'&Save','Button1')
    ;~         ControlFocus($hWnd,'Cancel','Button2')

    # VIII
            ;auto click save/cancel
    ;~         ControlClick($hWnd,"&Save", 'Button1','Left')
    ;~         ControlClick($hWnd,"Cancel", 'Button2','Left')


    # IX
        #--------------------------------------------------
        # ---OR--- skip all above steps and use this work around
        #--------------------------------------------------
    ;~     ControlSetText($hWnd, "Namespace", "Edit1", $AddressPath&'\'&$aFileName)

    EndFunc