質問

私が使う rsync サーバーに依存しない方法でファイルを Windows クライアントに同期します。rsync の進行状況を親プロセスに送信し、GUI の進行状況バーに表示するにはどのような方法がありますか?

選択肢は 2 ~ 3 つあると思います。(1) STDOUT を監視します。 (2) unix と同様の rsync.exe ログ ファイルを監視します。 tail (3) メモリ内の rsync コンソール出力を監視します。

どれが一番良い/好ましいですか?

役に立ちましたか?

解決

この種のタスクでは、私は独自のものを使用します 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

他のヒント

.NET には、STDOUT を読み取って監視するための非常に簡単な方法があります。
これは外部ファイルに依存せず、rsync へのパスのみに依存するため、これが最もクリーンな方法だと思います。ラッパー ライブラリが存在しても、私はそれほど驚かないでしょう。そうでない場合は、それを作成してオープンソースにしてください:)

このために独自の単純なオブジェクトを構築しました。これを再利用して、次のようにラップできます。 cmdline, web page, 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

チェックアウト デルタコピー. 。これは、rsync 用の Windows GUI です。

チェック NAバックアップ Windows ユーザーに Watch STDOUT を使用した Rsync GUI を提供するオープン ソース ソフトウェアです。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top