Reading System.Diagnostics.ProcessStartInfo StandardOutput como bytes en lugar de caracteres

Estoy intentando automatizar el volcado svnadmin usando C # ProcessStartInfo.

La forma en que lo hice en la línea de command es así,

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

Funciona como un regalo y se descarga exitosamente, y puedo verificar esto al restaurarlo en otro repository como ese

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

Que restaura con éxito – ¡yay!

Ahora … necesito replicar la tubería de línea de command en otro file usando C #, pero por alguna razón

 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; } } 

Vuelca el mismo repository en hackyhacky.svn_dump.

Pero cuando ejecuto mi línea de command de carga ahora

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

¡Recibo un error de sum de comprobación raro error!

 svnadmin load c:\Repositories\restre_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 

Supongo que esto tiene que ver con la forma en que estoy networkingirigiendo y leyendo el StandardOutput.

¿Alguien sabe la forma correcta de imitar el comportamiento de la tubería de línea de command en C #?

Cualquier ayuda es muy apreciada.

-CV

ACTUALIZAR

Intenté usar un BinaryWriter y usar el estándarOutputByteBuffer para escribir en el file, pero eso tampoco funciona. Me sale un error diferente sobre el formatting de encabezado incorrecto o algo así.

¡Bien! Si no puedes vencerlos, únete a ellos …

Encontré una publicación donde el autor canaliza a un file directamente dentro de Process StartInfo, y dice que funciona.

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

No funcionó para mí, como se describe en la publicación de otro caballero

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

Primero escribe un file por lotes con la tubería y luego lo ejecuta …

 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(); 

En sus palabras:

Verdaderamente horrible, ¡pero tiene la ventaja de funcionar!

Para ser franco, estoy un poco molesto de que esto me haya tomado tanto time como lo ha hecho, así que la solución de files por lotes funciona bien, así que me voy a quedar con eso.

Lo primero que intentaré es escribir la matriz de caracteres, no la matriz de bytes, en el file.

Eso debería funcionar siempre que el resultado sea solo text simple. Sin embargo, hay otros problemas de encoding, si el resultado es más complejo: está escribiendo el file como UTF-8, mientras que el valor pnetworkingeterminado para la salida de command-line (creo) es Windows-1252.

He estado tratando de hacer esto mismo y me encontré con otra solución al problema utilizado por el proyecto svnmanagerlib sourceforge de Hector Sosa :

La key para resolver esto fue rodear la llamada a WaitForExit () con operaciones de file. También es necesario para asegurarse de escribir la salida en el disco. Estas son las líneas relevantes:

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

Tenga en count que hago una llamada a File.AppendAllText () dos veces. He encontrado que la secuencia de salida no escribe todo durante la primera llamada a File.AppendAllText () en algunas ocasiones.

 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; }