2010-08-15 119 views
3

我想使用C#ProcessStartInfo自動化svnadmin轉儲。閱讀System.Diagnostics.ProcessStartInfo標準輸出爲字節,而不是字符

我已經做到了在命令行的方式是像這樣,

svnadmin dump c:\Repositories\hackyhacky > c:\backup\hackyhacky.svn_dump

作品一種享受,併成功地轉儲,我可以恢復到另一個倉庫,像這樣

驗證這一點

svnadmin load c:\Repositories\restore_test < c:\backup\hackyhacky.svn_dump

恢復成功 - 耶!

現在......我需要複製的命令行管道將使用C#另一個文件,但由於某種原因

var startInfo = new ProcessStartInfo(Path.Combine(SvnPath, "svnadmin"),"dump c:\Repositories\hackyhacky") 
{CreateNoWindow = true, RedirectStandardOutput = true,RedirectStandardError = true,UseShellExecute = false}; 
process.StartInfo = startInfo; 
process.Start(); 
StreamReader reader = process.StandardOutput; 
char[] standardOutputCharBuffer = new char[4096]; 
byte[] standardOutputByteBuffer; 
int readChars = 0; 
long totalReadBytes = 0; 

// read from the StandardOutput, and write directly into another file 

using (StreamWriter writer = new StreamWriter(@"C:\backup\hackyhacky.svn_dump", false)) { 
    while (!reader.EndOfStream) { 
     // read some chars from the standard out 
     readChars = reader.Read(standardOutputCharBuffer, 0, standardOutputCharBuffer.Length); 

     // convert the chars into bytes 
     standardOutputByteBuffer = reader.CurrentEncoding.GetBytes(standardOutputCharBuffer); 

     // write the bytes out into the file 
     writer.Write(standardOutputCharBuffer.Take(readChars).ToArray()); 

     // increment the total read 
     totalReadBytes += standardOutputByteBuffer.Length; 
    }      
} 

轉儲同一回購成hackyhacky.svn_dump。

但是當我現在運行我的負荷命令行

svnadmin load c:\Repositories\restore_test < c:\backup\hackyhacky.svn_dump

我得到一個校驗和錯誤奇怪的錯誤!

svnadmin load c:\Repositories\restore_test < c:\backup\hackyhacky.svn_dump 
< Started new transaction, based on original revision 1 
    * adding path : Dependencies ... done. 
    * adding path : Dependencies/BlogML.dll ...svnadmin: Checksum mismatch, fil 
e '/Dependencies/BlogML.dll': 
    expected: d39863a4c14cf053d01f636002842bf9 
    actual: d19831be151d33650b3312a288aecadd 

我猜這是關於如何重定向和閱讀StandardOutput。

有誰知道正確的方式來模仿C#中的命令行文件管道行爲?

任何幫助,非常感謝。

-CV

UPDATE

我使用的BinaryWriter和使用standardOutputByteBuffer寫入文件試過,但也不管用。我收到關於錯誤標題格式或其他內容的錯誤。

回答

1

好吧!如果你不能擊敗他們,加入他們....

我發現一個職位,作者管道直接在Process StartInfo內的文件,並聲稱它的作品。

http://weblogs.asp.net/israelio/archive/2004/08/31/223447.aspx

它沒有爲我工作,在另一個紳士的帖子

http://webcache.googleusercontent.com/search?q=cache:http://www.deadbeef.com/index.php/redirecting_the_output_of_a_program_to_a

他與管道第一寫一個批處理文件描述,然後執行它...

amWriter bat = File.CreateText("foo.bat"); 
bat.WriteLine("@echo off"); 
bat.WriteLine("foo.exe -arg >" + dumpDir + "\\foo_arg.txt"); 
bat.Close(); 
Process task = new Process(); 
task.StartInfo.UseShellExecute = false; 
task.StartInfo.FileName = "foo.bat"; 
task.StartInfo.Arguments = ""; 
task.Start(); 
task.WaitForExit(); 

用他的話說:

真正可怕的,但它具有 優勢的工作!

坦白地說,我有點惱火,這讓我只要有它,所以批處理文件解決方案效果很好,所以我會堅持下去。

0

我會嘗試的第一件事是將字符數組寫入文件中,而不是字節數組。

只要輸出只是簡單的文本,就應該工作。但是,如果輸出更復雜,還有其他編碼問題:您將文件編寫爲UTF-8,而命令行輸出(我相信)的默認值爲Windows-1252。

+0

謝謝斯蒂芬,我在當前的代碼中寫有char數組。我試着將字符切換成字節並寫入。這兩種方法都不起作用,併產生不同的錯誤 – CVertex 2010-08-15 09:48:52

0

我一直在努力做這事,只是偶然在另一solutionHector Sosa'ssvnmanagerlib SourceForge項目中使用的問題:

的關鍵,解決這個被周邊調用WaitForExit()與 文件操作。還需要確保將輸出寫入磁盤。 以下是相關行:

File.AppendAllText(destinationFile,myOutput.ReadToEnd()); svnCommand.WaitForExit(); File.AppendAllText(destinationFile, myOutput.ReadToEnd());

請注意,我對File.AppendAllText()進行了兩次調用。我發現 在某些情況下,輸出流在第一次調用 期間不會寫入所有內容到File.AppendAllText()。

public static bool ExecuteWritesToDiskSvnCommand(string command, string arguments, string destinationFile, out string errors) 
     { 
      bool retval = false; 
      string errorLines = string.Empty; 
      Process svnCommand = null; 
      ProcessStartInfo psi = new ProcessStartInfo(command); 

      psi.RedirectStandardOutput = true; 
      psi.RedirectStandardError = true; 
      psi.WindowStyle = ProcessWindowStyle.Hidden; 
      psi.UseShellExecute = false; 
      psi.CreateNoWindow = true; 

      try 
      { 
       Process.Start(psi); 
       psi.Arguments = arguments; 
       svnCommand = Process.Start(psi); 

       StreamReader myOutput = svnCommand.StandardOutput; 
       StreamReader myErrors = svnCommand.StandardError; 

       File.AppendAllText(destinationFile, myOutput.ReadToEnd()); 
       svnCommand.WaitForExit(); 
       File.AppendAllText(destinationFile, myOutput.ReadToEnd()); 

       if (svnCommand.HasExited) 
       { 
        errorLines = myErrors.ReadToEnd(); 
       } 

       // Check for errors 
       if (errorLines.Trim().Length == 0) 
       { 
        retval = true; 
       } 
      } 
      catch (Exception ex) 
      { 
       string msg = ex.Message; 
       errorLines += Environment.NewLine + msg; 
      } 
      finally 
      { 
       if (svnCommand != null) 
       { 
        svnCommand.Close(); 
       } 
      } 

      errors = errorLines; 

      return retval; 
     } 
相關問題