在 gui 中包装 rsync 进度的最佳方法? [英] Best way to wrap rsync progress in a gui?
问题描述
我使用 rsync 以与服务器无关的方式将文件同步到 Windows 客户端.有哪些方法可以将rsync的进度发送到父进程以在gui进度条中显示?
I use rsync to synchronize files to Windows clients in a server agnostic way. What methods are available to send the progress of rsync to the parent process for display in a gui progress bar?
我想有两三个选择.(1) Watch STDOUT (2) Watch rsync.exe 日志文件,类似于unix tail
(3) Watch rsync console output in memory.
I imagine two or three choices exist. (1) Watch STDOUT (2) Watch rsync.exe log file, similar to unix tail
(3) Watch rsync console output in memory.
哪一个是最好的/首选的?
Which one is best/preferred?
推荐答案
对于这类任务,我使用自己的 AutoIt 脚本(免费软件,仅限 Windows).该脚本将标准输出重定向到一个图形窗口,显示它并具有向后滚动等功能(在 XCOPY/PKZIP 等长进程中非常有用,以检查是否确实发生了任何错误).
For this type of tasks, I use my own AutoIt script (freeware, Windows only). The script redirects the standard output into a graphical window, displaying it with the ability to scroll back, etc (very useful in long processes like XCOPYs / PKZIPs to check if any error did happen).
我使用 AutoIt 是因为它是免费的,非常易于使用,并且可以快速编译为 .EXE.我认为这是完成此类任务的完整编程语言的绝佳替代品.缺点是它仅适用于 Windows.
I use AutoIt because it's free, very easy to use, and can compile quickly into an .EXE. I think it's an excellent alternative to a complete programming language for this type of tasks. The downside is that it's for Windows only.
$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
这篇关于在 gui 中包装 rsync 进度的最佳方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!