在 GUI 中包装 rsync 进度的最佳方法?

发布于 2024-07-04 03:39:24 字数 275 浏览 9 评论 0原文

我使用 rsync 以与服务器无关的方式将文件同步到 Windows 客户端。 有哪些方法可以将 rsync 的进度发送到父进程以在 GUI 进度条中显示?

我想存在两三个选择。 (1) 观察STDOUT (2) 观察rsync.exe日志文件,类似于unix tail (3) 观察内存中的rsync控制台输出。

哪一个最好/首选?

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?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

温暖的光 2024-07-11 03:39:25

请查看 DeltaCopy。 它是 rsync 的 Windows GUI。

Check out DeltaCopy. It is a Windows GUI for rsync.

阳光下的泡沫是彩色的 2024-07-11 03:39:25

检查 NAsBackup 它的开源软件,它为 Windows 用户提供使用 Watch STDOUT 的 Rsync GUI。

Check NAsBackup Its open source software that give Windows user Rsync GUI using Watch STDOUT.

眼波传意 2024-07-11 03:39:25

.NET 有一种非常直接的方式来读取和观看 STDOUT。
我想这将是最干净的方法,因为它不依赖于任何外部文件,只依赖于 rsync 的路径。 如果那里有一个包装库,我也不会太惊讶。 如果没有,请编写并开源它:)

.NET has a pretty straight forward way to read and watch STDOUT.
I guess this would be the cleanest way, since it is not dependent on any external files, just the path to rsync. I would not be too surprised if there is a wrapper library out there either. If not, write and open source it :)

风吹雨成花 2024-07-11 03:39:25

我为此构建了自己的简单对象,我从中得到了很多重用,我可以用 cmdlineweb pagewebservice 包装它,将输出写入文件等 -

注释项包含一些 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

I've built my own simple object for this, I get a lot of reuse out of it, I can wrap it with a cmdline, web page, webservice, write output to a file, etc---

The commented items contain some rsync examples--

what I'd like to do sometime is embed rsync (and cygwin) into a resource & make a single .net executable out of it--

Here you go:

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
深府石板幽径 2024-07-11 03:39:24

对于此类任务,我使用自己的 AutoIt 脚本(免费软件,仅限 Windows)。 该脚本将标准输出重定向到图形窗口,显示它并具有向后滚动的能力等(在 XCOPY / 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

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).

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文