Pergunta

eu uso sincronizar novamente para sincronizar arquivos com clientes Windows de maneira independente do servidor.Quais métodos estão disponíveis para enviar o progresso do rsync ao processo pai para exibição em uma barra de progresso da GUI?

Imagino que existam duas ou três opções.(1) Assistir STDOUT (2) Assistir ao arquivo de log rsync.exe, semelhante ao unix tail (3) Observe a saída do console rsync na memória.

Qual é o melhor/preferido?

Foi útil?

Solução

Para este tipo de tarefas, utilizo o meu próprio AutoIt script (freeware, somente Windows).O script redireciona a saída padrão para uma janela gráfica, exibindo-a com a capacidade de rolar para trás, etc. (muito útil em processos longos como XCOPYs/PKZIPs para verificar se algum erro aconteceu).

Eu uso o AutoIt porque é gratuito, muito fácil de usar e pode ser compilado rapidamente em um .EXE.Acho que é uma excelente alternativa a uma linguagem de programação completa para este tipo de tarefas.A desvantagem é que é apenas para 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

Outras dicas

O .NET tem uma maneira bastante simples de ler e assistir STDOUT.
Acho que essa seria a maneira mais limpa, já que não depende de nenhum arquivo externo, apenas do caminho para o rsync.Eu não ficaria muito surpreso se houvesse uma biblioteca wrapper por aí.Se não, escreva e abra o código :)

Eu construí meu próprio objeto simples para isso, posso reutilizá-lo bastante, posso envolvê-lo com um cmdline, web page, webservice, grave a saída em um arquivo, etc ---

Os itens comentados contêm alguns rsync exemplos--

o que eu gostaria de fazer algum dia é incorporar rsync (e cygwin) em um recurso e transforme-o em um único executável .net -

Aqui você vai:

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

Confira DeltaCopy.É uma GUI do Windows para rsync.

Verificar NAsBackup Seu software de código aberto que fornece ao usuário do Windows Rsync GUI usando Watch STDOUT.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top