将rsync进度包装在gui中的最佳方法?
时间:2020-03-05 18:39:00 来源:igfitidea点击:
我使用rsync以与服务器无关的方式将文件同步到Windows客户端。有哪些方法可以将rsync的进度发送到父进程以显示在gui进度栏中?
我想象有两个或者三个选择。 (1)观察STDOUT(2)观察rsync.exe日志文件,类似于unixtail
(3)观察内存中的rsync控制台输出。
哪个是最好的/首选的?
解决方案
回答
.NET具有一种非常简单的读取和观看STDOUT的方式。
我猜这将是最干净的方法,因为它不依赖于任何外部文件,而仅依赖于rsync的路径。如果那里也有包装器库,我也不会太惊讶。如果没有,请编写并开源:)
回答
签出DeltaCopy。这是用于rsync的Windows GUI。
回答
对于此类任务,我使用自己的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
回答
我为此构建了自己的简单对象,我从中获得了很多可重用性,我可以使用cmdline,web页面,webservice将其包装,将输出写入文件,等等-
注释的项目包含一些rsync
示例-
我有时想做的是将rsync
(和cygwin
)嵌入到资源中,并从中创建一个.net可执行文件,
干得好:
Imports System.IO Namespace cds Public Class proc Public _cmdString As String Public _workingDir As String Public _arg As String Public Function basic() As String Dim sOut As String = "" Try 'Set start information. 'Dim startinfo As New ProcessStartInfo("C:\Program Files\cwRsync\bin\rsync", "-avzrbP 192.168.42.6::cdsERP /cygdrive/s/cdsERP_rsync/gwy") 'Dim startinfo As New ProcessStartInfo("C:\Program Files\cwRsync\bin\rsync", "-avzrbP 10.1.1.6::user /cygdrive/s/cdsERP_rsync/gws/user") 'Dim startinfo As New ProcessStartInfo("C:\windows\system32\cscript", "//NoLogo c:\windows\system32\prnmngr.vbs -l") Dim si As New ProcessStartInfo(_cmdString, _arg) si.UseShellExecute = False si.CreateNoWindow = True si.RedirectStandardOutput = True si.RedirectStandardError = True si.WorkingDirectory = _workingDir ' Make the process and set its start information. Dim p As New Process() p.StartInfo = si ' Start the process. p.Start() ' Attach to stdout and stderr. Dim stdout As StreamReader = p.StandardOutput() Dim stderr As StreamReader = p.StandardError() sOut = stdout.ReadToEnd() & ControlChars.NewLine & stderr.ReadToEnd() 'Dim writer As New StreamWriter("out.txt", FileMode.CreateNew) 'writer.Write(sOut) 'writer.Close() stdout.Close() stderr.Close() p.Close() Catch ex As Exception sOut = ex.Message End Try Return sOut End Function End Class End Namespace
回答
Check NAsBackup它的开源软件,使用Watch STDOUT为Windows用户提供Rsync GUI。