2008-08-11 17 views
5

Używam rsync do synchronizowania plików z klientami Windows w sposób agnostyczny na serwerze. Jakie metody są dostępne, aby wysłać postęp rsync do procesu nadrzędnego do wyświetlenia na pasku postępu GUI?Najlepszy sposób na zawijanie postępu rsync w gui?

Wyobrażam sobie, że istnieją dwie lub trzy opcje. (1) Oglądaj STDOUT (2) Oglądaj plik dziennika rsync.exe podobny do unix tail (3) Oglądaj dane wyjściowe konsoli rsync w pamięci.

Który z nich jest najlepszy/preferowany?

Odpowiedz

2

Do tego typu zadań używam własnego skryptu AutoIt (darmowy, tylko Windows). Skrypt przekierowuje standardowe wyjście do okna graficznego, wyświetlając je z możliwością przewijania w tył itp. (Bardzo przydatne w długich procesach, takich jak XCOPYs/PKZIP, w celu sprawdzenia, czy nie wystąpił błąd).

Używam AutoIt, ponieważ jest darmowy, bardzo łatwy w użyciu i może szybko skompilować do .EXE. Myślę, że jest to doskonała alternatywa dla pełnego języka programowania dla tego typu zadań. Minusem jest to, że jest tylko dla 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 ma dość prosty sposób czytania i oglądania STDOUT.
Myślę, że byłby to najczystszy sposób, ponieważ nie jest zależny od plików zewnętrznych, tylko ścieżka do rsync. Nie byłbym zbyt zaskoczony, gdyby istniała tam również biblioteka otworkowa. Jeśli nie, napisz i otwórz to źródło :)

0

Zapoznaj się z DeltaCopy. Jest to graficzny interfejs użytkownika systemu Windows dla rsync.

1

ja zbudowałem mój własny prosty obiekt do tego, dostaję dużo ponownego użycia z nim, mogę zawinąć go z cmdline, web page, webservice, zapis danych do pliku, itd ---

komentowanym pozycje zawierają niektóre rsync examples--

co chciałbym zrobić kiedyś się osadzić rsync (i cygwin) do zasobu & uczynić pojedynczy .net wykonywalny z it--

Proszę bardzo:

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

Skontrolować NAsBackup swojego oprogramowania open source, które dają użytkownikowi systemu Windows za pomocą rsync GUI Watch standardowe wyjście.