Read output from svn into a string
Ok, so after my ide开发者_StackOverflowa of SSHing to a server and using the svn command line client instead of remote desktop (not much of an idea tbh), me and my boss have decided it would be rather better if we could update each project from a single local web-page (this is only for our development server). Now, I did get this to work (once), however it often does not.
I am using the following code:
ProcessStartInfo start = new ProcessStartInfo("C:\Program Files (x86)\CollabNet\Subversion Client\svn.exe", "update " + UpdatePath);
start.RedirectStandardOutput = true;
start.UseShellExecute = false;
start.ErrorDialog = false;
start.CreateNoWindow = true;
start.WindowStyle = ProcessWindowStyle.Hidden;
Process process = Process.Start(start);
StreamReader output = process.StandardOutput;
string text = output.ReadToEnd();
process.WaitForExit();
Response.Write(text + "<br />" + UpdatePath);
in theory, this should collect the output from the svn app, and write it to the page, however it does not (unless in the rare case when it actually updated, however that is not when I particularly need the output!)
Can anyone spot the problem?
Here is some code taken from one of my apps - its basically just the MSDN sample. (http://msdn.microsoft.com/en-us/library/system.diagnostics.process.outputdatareceived.aspx)
private void SvnOutputHandler(object sendingProcess,
DataReceivedEventArgs outLine)
{
Process p = sendingProcess as Process;
// Save the output lines here
}
private void RunSVNCommand()
{
ProcessStartInfo psi = new ProcessStartInfo("svn.exe",
string.Format("update \"{0}\" {1}", parm1, parm2));
psi.UseShellExecute = false;
psi.CreateNoWindow = true;
// Redirect the standard output of the sort command.
// This stream is read asynchronously using an event handler.
psi.RedirectStandardOutput = true;
psi.RedirectStandardError = true;
Process p = new Process();
// Set our event handler to asynchronously read the sort output.
p.OutputDataReceived += SvnOutputHandler;
p.ErrorDataReceived += SvnOutputHandler;
p.StartInfo = psi;
p.Start();
p.BeginOutputReadLine();
p.BeginErrorReadLine();
p.WaitForExit()
}
Not quite an answer to your original question, but a different approach might be to use SharpSvn (http://sharpsvn.open.collab.net). By giving you more direct access to the API, it might give you better control and results.
I've used it to monitor and update svn work areas and it seemed to get the job done.
I think you need to move
StreamReader output = process.StandardOutput;
string text = output.ReadToEnd();
after WaitToExit()
You may also want to redirect standard error in case something bad happens, you probably want to know about it.
Also you can shorten your code by doing string text= process.StandardOutput.ReadToEnd();
You will need to periodically read from the standard output pipe of the process while it is running. If you don't do this, then the standard output buffer will fill up and Windows will suspend the process and wait until it's clear before continuing. Of course, your process is sitting in a WaitForExit()
so you have a deadlock.
This is a generic answer because I'm not familiar enough with the .NET process management primitives to give an example. However, the principle is the same as in any other piped output system.
First I would recomend Rusty's suggestion. Secondly you can review this code for a working example of capturing process output.
If you just want to use the wrapper class from the link here is what you need:
using CSharpTest.Net.Processes;
static void Update(string sourcePath, Action<string> output)
{
ProcessRunner run = new ProcessRunner("svn.exe", "update", "{0}");
run.OutputReceived +=
delegate(Object o, ProcessOutputEventArgs e) { output(e.Data); };
int exitCode = run.RunFormatArgs(sourcePath);
if (exitCode != 0)
throw new ApplicationException(
String.Format("SVN.exe returned {0}.", exitCode)
);
}
精彩评论