找回密码
 加入
搜索
查看: 4578|回复: 9

[AU3基础] robocopy UDF 问题

  [复制链接]
发表于 2011-6-25 23:41:25 | 显示全部楼层 |阅读模式
本帖最后由 hzxymkb 于 2011-6-25 23:52 编辑

这个UDF是从官网找到的,运行不了!请高手帮一下!
#include <Constants.au3> ; STDIN & STDOUT
;Global Const $STDIN_CHILD              = 1
;Global Const $STDOUT_CHILD             = 2
;Global Const $STDERR_CHILD             = 4
;Global Const $STDERR_MERGED            = 8
;Global Const $STDIO_INHERIT_PARENT     = 0x10
;Global Const $RUN_CREATE_NEW_CONSOLE   = 0x00010000
;===============================================================================
;
; Function Name:    _robocopy($source, $target, $stitches = "mirror", $excludeFiles = "", $excludeFolders = "", $logFile = "", $statusBox = "", $progressBar = "")
; Description::     Runs the Robocopy command
; Parameter(s):     $source     -   Source directory
;                   $target     -   Target Directory
;                   $stitches   -   Standard Robocopy switches, predefined meta commands or combination of both
;                               -   "Meta" or "Std Switches" or [meta][Space][Std switches] (eg mirror /r:0 /w:0)
;                               -   Mirror - Clone source to target (includeing subdirectories)
;                               -   Add - Add new/updates files but don't delete anything
;                               -   Copy - Same as Add
;                               -   CopySub - Same as add but also copies all subdirectories
;                               -   Move - Move files to destination
;                               -   MoveSub - Same as move but also copies all subdirectories
;                   $includeFiles   -   A list of files to include (Comma delimited)
;                                   -   OR An array of files
;                   $excludeFiles   -   A list of files to exclude (Comma delimited)
;                                   -   OR An array of files
;                   $excludeFolders -   A list of folders to exclude (Comma delimited)
;                                   -   OR An array of files
;                   $logFile        -   Filename for log file
;                                       If File starts with + then append to log
;                   $outputFunction -   Function name to pass text to from robocopy
;                                   -   Only full lines will be passed to this function
;                                   -   This will be run by execute command in the form {Function name}($text)
; Requirement(s):  Robocopy is installed on the computer or in the same directoy as script
; Return Value(s): Success: ???
;                   Error: 0 and @error =
;                   = 1 - Robocopy.exe can't be found
;                   = 2 - Source doesn't Exist
;                   = 3 - Destination can't be created (eg maybe read only media)
;                   = 4 - Log File can't be created
;                   = 5 - Robocopy Cant' be run
; Author(s):       John Morrison
;
; Basis:
; Thanks:   PsaltyDS http://www.autoitscript.com/forum/index....p?showtopic=98602&view=findpos _ProcessGetExitCode()
;===============================================================================
Func _robocopy($source, $target, $switches = "mirror", $includeFiles = "", $excludeFiles = "", $excludeFolders = "", $logFile = "", $outputFunction = "")
    #cs
    ConsoleWrite("All Switches" & @CR & _
            "$source = <" & $source & ">" & @CR & _
            "$target = <" & $target & ">" & @CR & _
            "$switches = <" & $switches & ">" & @CR & _
            "$includeFiles = <" & $includeFiles & ">" & @CR & _
            "$excludeFolders = <" & $excludeFolders & ">" & @CR & _
            "$logFile = <" & $logFile & ">" & @CR & _
            "$outputFunction = <" & $outputFunction & ">" & @CR)
    #ce

    ; Check if Robocopy can be executed
    Local $roboCopyCMD = ""
    While $roboCopyCMD = ""
        If FileExists(@SystemDir & "\robocopy.exe") Then
            $roboCopyCMD = @SystemDir & "\robocopy.exe "
        ElseIf FileExists(@ScriptDir & "\robocopy.exe") Then
            $roboCopyCMD = @ScriptDir & "\robocopy.exe "
        ElseIf FileExists(@ScriptDir & "\getrobocopy.exe") Then
            ;Download Robocopy
            If RunWait(@ScriptDir & "\getrobocopy.exe", @TempDir) <> 0 Then
                Return SetError(1, "", 0) ; Can't find Robocopy
            EndIf
        Else
            Return SetError(1, "", 0) ; Can't find Robocopy
        EndIf
    WEnd

    $workingdir = $source
    ; Check source exists
    If StringRight($source, 1) = "" Then
        ; remove trailing slash \
        $source = StringLeft($source, StringLen($source) - 1)
    EndIf
    If Not FileExists($source) Then
        ; source doesn't exist
        Return SetError(2, "", 0) ; Source doesn't Exist
    EndIf
    $source = _RCProcessFilelist($source)

    ; Check Target reachable
    If StringRight($target, 1) = "" Then
        ; remove trailing slash \
        $target = StringLeft($target, StringLen($target) - 1)
    EndIf
    If Not FileExists($target) Then
        If Not DirCreate($target) Then
            Return SetError(3, "", 0) ; Destination can't be created (eg maybe read only media)
        EndIf
    EndIf
    $target = _RCProcessFilelist($target)

    ;Workout Robocopy switches from Meta
    While 1
        ;Loop until all metas are removed
        Select
            ;Case _RCcheckMeta("sub", "/E", $switches)
            Case _RCcheckMeta("mirror", "/MIR ", $switches)
            Case _RCcheckMeta("Add", "", $switches)
            Case _RCcheckMeta("Copy", "", $switches)
            Case _RCcheckMeta("CopySub", "/E", $switches)
            Case _RCcheckMeta("Move", "/MOVE", $switches)
            Case _RCcheckMeta("MoveSub", "/MOVE /E", $switches)
            Case Else
                ;MsgBox(0, "pause", "META EKSE")
                ExitLoop
        EndSelect
        ;MsgBox(0, "pause", "META")
    WEnd

    ;Include files
    If $includeFiles = "" Then $includeFiles = "*.*"
    $switches = _RCProcessFilelist($includeFiles) & " " & StringStripWS($switches, 1)

    ;Exclude files/folders
    If $excludeFiles <> "" Then
        $switches &= " /XF " & _RCProcessFilelist($excludeFiles)
    EndIf
    If $excludeFolders <> "" Then
        ; Add target to 'excluded files' in case tragete is inside source (eg source=c: target=c:\backup)
        $switches &= " /XD " & _RCProcessFilelist($excludeFolders) & " " & _RCProcessFilelist($target)
    EndIf

    ; LOG
    If $logFile <> "" Then
        If StringLeft($logFile, 1) = "+" Then
            $logFile = StringMid($logFile, 2, 255)
            $switches &= ' /log+:"' & $logFile & '"'
        Else
            $switches &= ' /log:"' & $logFile & '"'
        EndIf

        $hfile = FileOpen($logFile, 1)
        If $hfile = -1 Then
            Return SetError(4, "", 0) ;Can't append/create Log file error
        EndIf
        FileClose($hfile)
    EndIf

    ;Add extra switches if nessacary
    If Not StringInStr($switches, "/r:") Then
        ; retry count
        $switches &= " /r:0"
    EndIf
    If Not StringInStr($switches, "/w:") Then
        ; Wait time
        $switches &= " /w:0"
    EndIf
    If Not StringInStr($switches, "/ZB") Then
        ; Tries to copy files in restartable mode, but if that fails with an “Access Denied” error, switches automatically to Backup mode.
        ;TODO - MAY drop this out as slows copy ???
        $switches &= " /ZB"
    EndIf
    If Not StringInStr($switches, "/FFT") Then
        ; Assume FAT File Times (2-second granularity). Useful for copying to third-party systems that declare a volume to be NTFS but only implement file times with a 2-second granularity..
        $switches &= " /FFT"
    EndIf
    If Not StringInStr($switches, "/COPY:") Then
        ; Copies Data, Attributes, Timestamps only (SEE
        $switches &= " /COPY:DAT"
    EndIf
    ; Wasn't as useful as it looked-  removed
    ;If Not StringInStr($switches, "/ETA") Then
    ;   ; Shows estimated time of completion for copied files.
    ;   $switches &= " /ETA"
    ;EndIf
    If StringInStr($switches, "/log") Then
        ; Displays output in the console window, in addition to directing it to the log file specified by /LOG or /LOG+.
        ; Needed for status and progress displays
        $switches &= " /TEE"
    EndIf
    ; DEGUB TODO - remove commenting after testing
    ;If $progressBar = "" Then
    ;   ; no progress bar so "suppress the display of progress information"
    ;   $switches &= " /NP "
    ;EndIf

#cs
    MsgBox(0, "ROBOCOPY", _
            "$source = <" & $source & ">" & @CR & _
            "$target = <" & $target & ">" & @CR & _
            "$switches = <" & $switches & ">" & @CR & _
            "$roboCopyCMD = <" & $roboCopyCMD & " " & $source & " " & $target & " " & $switches & ">" & @CR & _
            "")
            #ce
    ConsoleWrite($roboCopyCMD & " " & $source & " " & $target & " " & $switches & @CR)

    ;Exit

    ; run robocopy
    Local $robocopyPID = Run('"' & $roboCopyCMD & '" ' & $source & " " & $target & " " & $switches, $workingdir, @SW_HIDE, $STDIN_CHILD + $STDOUT_CHILD)
    If $robocopyPID = 0 Then
        Return SetError(5, "", 0) ; Robocopy failed to run
    Else
        Local $hrobocopy = _ProcessGetHandle($robocopyPID)
        ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $hrobocopy = ' & $hrobocopy & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console
        If @error Then MsgBox(0,"Error _ProcessGetHandle", "@error = " & @error)

        Local $cmdOut, $cmdoutlast, $buffer, $loopCount, $buffer2, $sPosit
        ;Local $cmdOutErr = 1 ; so loop is run at least once
        While 1 ; ProcessExists($robocopyPID); Or ($cmdOutErr = 0) ; $cmdOurErr - used to wait untill ALL data is extracted from command line

            $cmdOut = StdoutRead($robocopyPID)
            ;$cmdOutErr = @error
            If @error Then ExitLoop

            If $cmdOut <> $cmdoutlast Then
                $cmdoutlast = $cmdOut
                $fnewdata = True
                $buffer &= $cmdOut ; Stores all data for processing

                ;interpret $BUFFER data
                ;extract and send to $statusFunc() the buffer string up to and including the last @CRLF
                $posit = StringInStr($buffer, @CRLF, 0, -1) + 2
                If Not @error Then
                    $buffer2 = StringStripWS(StringLeft($buffer, $posit), 2)
                    If $buffer2 <> "" Then
                        ;ConsoleWrite($posit & "|" & StringLen($buffer) & "<<" & $buffer2 & ">>" & Asc(StringMid($buffer, $posit, 1)) & "|" & $buffer & "|" & @CR)
                        Execute($outputFunction & '("' & $buffer2 & '")')
                    EndIf
                    $buffer = StringMid($buffer, $posit, 1000)
                    ;ConsoleWrite("<<<" & StringMid($buffer, $posit, 1000) & ">>>" & @CR)

                EndIf
            EndIf ; $cmdOut
            ;endif ; $outputFunction

            Sleep(20)
        WEnd

        Local $iReturnCode = _ProcessGetExitCode($hrobocopy)
        ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $iReturnCode = ' & $iReturnCode & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console
        If @error Then MsgBox(0,"Error _ProcessGetExitCode", "@error = " & @error)
        #cs
            BITMAP
            Value   Meaning If Set
            16  Serious error. Robocopy did not copy any files. This is either a usage error or an error due to insufficient access privileges on the source or destination directories.
            8   Some files or directories could not be copied (copy errors occurred and the retry limit was exceeded). Check these errors further.
            4   Some Mismatched files or directories were detected. Examine the output log. Housekeeping is probably necessary.
            2   Some Extra files or directories were detected. Examine the output log. Some housekeeping may be needed.
            1   One or more files were copied successfully (that is, new files have arrived).
            0   No errors occurred, and no copying was done. The source and destination directory trees are completely synchronized.
        #ce
        _ProcessCloseHandle($hrobocopy)
        If @error Then MsgBox(0,"Error _ProcessCloseHandle", "@error = " & @error)

        Return $iReturnCode
    EndIf

EndFunc   ;==>_robocopy

Func _RCcheckMeta($meta, $metaSwitch, ByRef $switches)
    ;check if meta is the first part of $switches or whole of switches
    ; if so replace with Robocopy switches for that meta
    $meta = StringLower($meta)
    If StringInStr($switches, $meta & " ") = 1 Or StringLower($switches) = $meta Then
        $switches = StringStripWS(StringStripWS($metaSwitch & " " & StringStripWS(StringMid($switches, StringLen($meta) + 1, 100), 1), 1), 2)
        Return True
    Else
        Return False
    EndIf
EndFunc   ;==>_RCcheckMeta

Func _RCProcessFilelist($fileList)
    ; $includeFiles = either a comma delimited string or Array of strings
    Local $sReturn = ""

    If Not IsArray($fileList) Then
        ;Standard string so convert to array
        $fileList = StringSplit($fileList, ",", 2)
    EndIf

    For $item = 0 To UBound($fileList) - 1
        $fileList[$item] = StringStripWS(StringStripWS($fileList[$item], 1), 2)
        If StringLeft($fileList[$item], 1) <> '"' Then ;Search for inverted commas as first character
            $fileList[$item] = '"' & $fileList[$item]
        EndIf
        If StringRight($fileList[$item], 1) <> '"' Then ;Search for inverted commas as first character
            $fileList[$item] &= '"'
        EndIf
        $sReturn &= " " & $fileList[$item]
    Next
    Return StringStripWS($sReturn, 1) ; Strip leading space
EndFunc   ;==>_RCProcessFilelist

; Return handle of given PID
Func _ProcessGetHandle($iPID)
    Local Const $PROCESS_QUERY_INFORMATION = 0x0400
    Local $avRET = DllCall("kernel32.dll", "ptr", "OpenProcess", "int", $PROCESS_QUERY_INFORMATION, "int", 0, "int", $iPID)
    If @error Then
        Return SetError(1, 0, 0)
    Else
        Return $avRET[0]
    EndIf
EndFunc   ;==>_ProcessGetHandle

; Close process handle
Func _ProcessCloseHandle($hProc)
    Local $avRET = DllCall("kernel32.dll", "int", "CloseHandle", "ptr", $hProc)
    If @error Then
        Return SetError(1, 0, 0)
    Else
        Return 1
    EndIf
EndFunc   ;==>_ProcessCloseHandle

; Get process exit code from handle
Func _ProcessGetExitCode($hProc)
    Local $t_ExitCode = DllStructCreate("int")
    Local $avRET = DllCall("kernel32.dll", "int", "GetExitCodeProcess", "ptr", $hProc, "ptr", DllStructGetPtr($t_ExitCode))
    If @error Then
        Return SetError(1, 0, 0)
    Else
        Return DllStructGetData($t_ExitCode, 1)
    EndIf
EndFunc   ;==>_ProcessGetExitCode
这段代码运行出错,可能是我不会使用,求高手哥指点一下小弟!


 这个是代码运行所需要的XP下的文件!

官网地址:http://www.autoitscript.com/foru ... arch__1#entry890595

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?加入

×
发表于 2011-6-25 23:45:41 | 显示全部楼层
我是菜鸟帮顶!!等高手来解答,p神,a神等等的大神快来啊!!!顶起

评分

参与人数 1金钱 +10 收起 理由
hzxymkb + 10 感谢您帮顶!

查看全部评分

发表于 2011-6-25 23:49:50 | 显示全部楼层
干你,,还又这加分一说! 1024

评分

参与人数 1金钱 +10 收起 理由
hzxymkb + 10

查看全部评分

发表于 2011-6-25 23:50:53 | 显示全部楼层
路过,实在看不懂,只能帮顶贴了,

评分

参与人数 1金钱 +10 收起 理由
hzxymkb + 10

查看全部评分

发表于 2011-6-26 00:34:56 | 显示全部楼层
Function Name:    _robocopy($source, $target, $stitches = "mirror", $excludeFiles = "", $excludeFolders = "", $logFile = "", $statusBox = "", $progressBar = "")
; Description::     Runs the Robocopy command
; Parameter(s):     $source     -   Source directory
;                   $target     -   Target Directory
;                   $stitches   -   Standard Robocopy switches, predefined meta commands or combination of both
;                               -   "Meta" or "Std Switches" or [meta][Space][Std switches] (eg mirror /r:0 /w:0)
;                               -   Mirror - Clone source to target (includeing subdirectories)克隆源到目标(includeing子目录)
;                               -   Add - Add new/updates files but don't delete anything添加 - 添加新/更新文件,但不删除任何

;                               -   Copy - Same as Add 复制 - 相同
;                               -   CopySub - Same as add but also copies all subdirectories 添加相同,但也将所有子目录
;                               -   Move - Move files to destination 移动文件到目的地
;                               -   MoveSub - Same as move but also copies all subdirectories
;                   $includeFiles   -   A list of files to include (Comma delimited)文件清单
;                                   -   OR An array of files
;                   $excludeFiles   -   A list of files to exclude (Comma delimited)排除文件

;                                   -   OR An array of files
;                   $excludeFolders -   A list of folders to exclude (Comma delimited)排除目录
;                                   -   OR An array of files
;                   $logFile        -   Filename for log file 文件日志
;                                       If File starts with + then append to log
;                   $outputFunction -   Function name to pass text to from robocopy
;                                   -   Only full lines will be passed to this function
;                                   -   This will be run by execute command in the form {Function name}($text)
发表于 2011-6-26 06:37:47 | 显示全部楼层
回复 1# hzxymkb


    试了下,可以用呀,直接用就可以了

#include "_robocopy.au3"
_robocopy("f:\PicPick", "d:\picpick", "/MIR /r:0 /w:0 /ZB /FFT /COPY:DAT")
发表于 2011-6-26 06:41:53 | 显示全部楼层
不过,写这个已经没有多大意思,微软已经把这个搞成有gui窗口的了。并且Win7下的还是多线程的
发表于 2011-6-26 09:59:13 | 显示全部楼层
大哥,我是来顶贴的
发表于 2011-7-2 15:54:31 | 显示全部楼层
我这边也是可以用的哦。
发表于 2011-7-2 16:46:01 | 显示全部楼层
顶下顶下顶下
您需要登录后才可以回帖 登录 | 加入

本版积分规则

QQ|手机版|小黑屋|AUTOIT CN ( 鲁ICP备19019924号-1 )谷歌 百度

GMT+8, 2024-9-21 03:20 , Processed in 0.088883 second(s), 25 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表