2008-08-11 2 views
5

Я использую rsync для синхронизации файлов с клиентами Windows на агностическом пути сервера. Какие методы доступны для отправки прогресса rsync в родительский процесс для отображения в панели выполнения gui?Лучший способ обернуть rsync прогресс в gui?

Я предполагаю, что существует два или три варианта. (1) Смотреть STDOUT (2) Смотреть файл журнала rsync.exe, аналогично unix tail (3) Смотреть вывод консоли rsync в памяти.

Какой из них является лучшим/предпочтительным?

ответ

2

Для этого типа задач я использую собственный скрипт AutoIt (бесплатная, только для Windows). Сценарий перенаправляет стандартный вывод в графическое окно, отображая его с возможностью прокрутки назад и т. Д. (Очень полезно в длинных процессах, таких как XCOPYs/PKZIP, чтобы проверить, произошла ли какая-либо ошибка).

Я использую 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 
1

.NET имеет довольно прямой способ читать и смотреть STDOUT.
Я предполагаю, что это был бы самый чистый способ, поскольку он не зависит от каких-либо внешних файлов, а только от пути к rsync. Я не был бы слишком удивлен, если бы там была оберточная библиотека. Если нет, напишите и с открытым исходным кодом:

0

Отъезд DeltaCopy. Это графический интерфейс Windows для rsync.

1

Я построил свой собственный простой объект для этого, я получаю много повторного использования из него, я могу обернуть его с cmdline, web page, webservice, записать вывод в файл, и т.д. ---

комментируемые элементы содержат некоторые rsync examples--

, что я хотел бы сделать когда-нибудь будут встраивать rsynccygwin) в ресурс & сделать один .net исполняемым из it--

Здесь вы идете:

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 
0

Регулярно проверяйте NAsBackup Его с открытым исходным кодом программного обеспечения, которые дают пользователю Windows, Rsync GUI с помощью Watch STDOUT.

Смежные вопросы