rsyncの進行状況をGUIでラップする最良の方法は?
-
08-06-2019 - |
質問
私が使う 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 を提供するオープン ソース ソフトウェアです。