windows - 在 gui 中包装 rsync 进度的最佳方法?

标签 windows user-interface rsync

我使用 rsync以与服务器无关的方式将文件同步到 Windows 客户端。有哪些方法可以将rsync的进度发送给父进程以gui进度条显示?

我想存在两个或三个选择。 (1) watch STDOUT (2) watch rsync.exe log file,类似于unix tail (3) watch rsync console output in memory.

哪个最好/首选?

最佳答案

对于此类任务,我使用自己的 AutoIt脚本(免费软件,仅限 Windows)。该脚本将标准输出重定向到一个图形窗口,显示它并具有向后滚动等功能(在 XCOPYs/PKZIPs 等长进程中非常有用,以检查是否确实发生了任何错误)。

我使用 AutoIt,因为它是免费的,非常易于使用,并且可以快速编译成 .EXE。我认为它是完成此类任务的完整编程语言的绝佳替代品。缺点是它仅适用于 Windows。

$sCmd = "DIR E:\*.AU3 /S"  ; Test command
$nAutoTimeout = 10      ; Time in seconds to close window after finish

$nDeskPct = 60          ; % of desktop size (if percent)

; $nHeight = 480          ; height/width of the main window (if fixed)
; $nWidth = 480

$sTitRun = "Executing process. Wait...."     ; 
$sTitDone = "Process done"                ; 

$sSound = @WindowsDir & "\Media\Ding.wav"       ; End Sound

$sButRun = "Cancel"                           ; Caption of "Exec" button
$sButDone = "Close"                            ; Caption of "Close" button

#include <GUIConstants.au3>
#include <Constants.au3>
#Include <GuiList.au3>

Opt("GUIOnEventMode", 1)

if $nDeskPct > 0 Then
    $nHeight = @DesktopHeight * ($nDeskPct / 100)
    $nWidth = @DesktopWidth * ($nDeskPct / 100)
EndIf


If $CmdLine[0] > 0 Then
    $sCmd = ""
    For $nCmd = 1 To $CmdLine[0]
        $sCmd = $sCmd & " " & $CmdLine[$nCmd]
    Next

    ; MsgBox (1,"",$sCmd)
EndIf

; AutoItSetOption("GUIDataSeparatorChar", Chr(13)+Chr(10))

$nForm = GUICreate($sTitRun, $nWidth, $nHeight)
GUISetOnEvent($GUI_EVENT_CLOSE, "CloseForm")

$nList = GUICtrlCreateList ("", 10, 10, $nWidth - 20, $nHeight - 50, $WS_BORDER + $WS_VSCROLL)
GUICtrlSetFont (-1, 9, 0, 0, "Courier New")

$nClose = GUICtrlCreateButton ($sButRun, $nWidth - 100, $nHeight - 40, 80, 30)
GUICtrlSetOnEvent (-1, "CloseForm")

GUISetState(@SW_SHOW)   ;, $nForm)

$nPID = Run(@ComSpec & " /C " & $sCmd, ".", @SW_HIDE, $STDOUT_CHILD)
; $nPID = Run(@ComSpec & " /C _RunErrl.bat " & $sCmd, ".", @SW_HIDE, $STDOUT_CHILD)     ; # Con ésto devuelve el errorlevel en _ERRL.TMP

While 1
    $sLine = StdoutRead($nPID)
    If @error Then ExitLoop

    If StringLen ($sLine) > 0 then
        $sLine = StringReplace ($sLine, Chr(13), "|")
        $sLine = StringReplace ($sLine, Chr(10), "")
        if StringLeft($sLine, 1)="|" Then
            $sLine = " " & $sLine
        endif

        GUICtrlSetData ($nList, $sLine)

        _GUICtrlListSelectIndex ($nList, _GUICtrlListCount ($nList) - 1)
    EndIf
Wend

$sLine = " ||"
GUICtrlSetData ($nList, $sLine)
_GUICtrlListSelectIndex ($nList, _GUICtrlListCount ($nList) - 1)

GUICtrlSetData ($nClose, $sButDone)

WinSetTitle ($sTitRun, "", $sTitDone)
If $sSound <> "" Then
    SoundPlay ($sSound)
EndIf

$rInfo = DllStructCreate("uint;dword")      ; # LASTINPUTINFO
DllStructSetData($rInfo, 1, DllStructGetSize($rInfo));

DllCall("user32.dll", "int", "GetLastInputInfo", "ptr", DllStructGetPtr($rInfo))
$nLastInput = DllStructGetData($rInfo, 2)

$nTime = TimerInit()

While 1
    If $nAutoTimeout > 0 Then
        DllCall("user32.dll", "int", "GetLastInputInfo", "ptr", DllStructGetPtr($rInfo))
        If DllStructGetData($rInfo, 2) <> $nLastInput Then
            ; Tocó una tecla
            $nAutoTimeout = 0
        EndIf
    EndIf

    If $nAutoTimeout > 0 And TimerDiff ($nTime) > $nAutoTimeOut * 1000 Then
        ExitLoop
    EndIf

    Sleep (100)
Wend


Func CloseForm()
    Exit
EndFunc

关于windows - 在 gui 中包装 rsync 进度的最佳方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8004/

相关文章:

PHP使用windows账号连接SQL Server

c++ - 覆盖文件而不会有损坏文件的风险

c++ - StillImage::GetDeviceList 指针

linux - 用于 rsync ssh 用户输入的 bash 脚本

python - 调用 Python 3.x 命令的跨平台方式

java - 通过代码关闭 fxml 窗口,javafx

jquery - 如何检查表单是否已更改

eclipse - Ubuntu 上 Eclipse 中的巨大选项卡

linux - 将数据从一个安装迁移到另一个安装

linux - 为什么这个 rsync 命令没有删除?