How to get SVN Commit log using c# Process - c#

I need to get the commit log by date for a svn project using C# application i.e if we have provided the URl , start and end date , we should use the svn.exe in a process to get log details
I have use the command svn log -r {"2007-07-07"}:{2019-11-08} to get the log in command prompt.
SourcePath = args[0]; // URL link
var startDate = args[1];
var endDate = args[2];
var svnSource = args[3]; // svn.exe location in my machine
var cmd1 = "cd /";
var cmd2 = "c:";
var cmd3 = string.Concat("cd ", svnSource);
var cmd4 = string.Concat("svn log ", SourcePath, " -r {", startDate, "}:{", endDate, "}");
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = "svn.exe";
startInfo.RedirectStandardInput = true;
startInfo.RedirectStandardOutput = true;
startInfo.RedirectStandardError = true;
startInfo.UseShellExecute = false;
Process process = new Process();
process.StartInfo = startInfo;
process.Start();
process.StandardInput.WriteLine(cmd1);
process.StandardInput.WriteLine(cmd2);
process.StandardInput.WriteLine(cmd3);
process.StandardInput.WriteLine(cmd4);
while (!process.StandardOutput.EndOfStream)
{
string line = process.StandardOutput.ReadLine();
if (!string.IsNullOrEmpty(line))
{
if (!process.HasExited)
{
}
}
}
I expect the result in the string "line" with all log values but i am getting actual output value as empty. breakpoint does not hit the "while (!process.StandardOutput.EndOfStream)" part itself while debugging.
How to resolve this ? what am i doing wrong here?

First of all, svn.exe will not interpret commands like that, so instead you should start a shell like cmd.exe.
If you're supplying a URL for your SourcePath then svn can run from anywhere from cmd, so you don't need the first 3 commands at all: cmd1, cmd2, cmd3.
That being said, you're not gonna need the svnSource variable either.
Of course, you can cd to the root directory to make your output look cleaner.
So these are the modifications I made to your code:
var SourcePath = args[0]; // URL link
var startDate = args[1];
var endDate = args[2];
var cmd1 = "cd c:\\";
var cmd2 = string.Concat("svn log ", SourcePath, " -r {", startDate, "}:{", endDate, "}");
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = "cmd.exe";
startInfo.RedirectStandardInput = true;
startInfo.RedirectStandardOutput = true;
startInfo.RedirectStandardError = true;
startInfo.UseShellExecute = false;
Process process = new Process();
process.StartInfo = startInfo;
process.Start();
process.StandardInput.WriteLine(cmd1);
process.StandardInput.WriteLine(cmd2);
// It's always a good idea to close your standard input when you're not gonna need it anymore,
// otherwise the process will wait indefinitely for any input and your while condition will never
// be true or in other words it will become an infinite loop...
process.StandardInput.Close();
string result = string.Empty; // for storing the svn commit log
while (!process.StandardOutput.EndOfStream)
{
string line = process.StandardOutput.ReadLine();
if (!string.IsNullOrEmpty(line))
{
if (!process.HasExited)
{
result += line + Environment.NewLine;
}
}
}

Related

Run Python 2.7 sript from C# with command line params

How do I run this python 2.7 code from C# (file name is myPythonScript.py):
import argparse
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument(
'-sd', '-start_date', help='start date to download data')
parser.add_argument(
'-ed', '-end_date', help='end date to download data')
args = parser.parse_args()
#print(args.accumulate(args.start_date))
print(args.sd, args.ed)
Above code only takes two dates as command line params and shows it to the user. I want to run it as a process from C#.
When I use this C# code it runs script without params well. But when I add params it can`t find python file. Why? How to resolve this?
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = #"C:\Anaconda2\python.exe";
// path to my python script
string appEXE = AppDomain.CurrentDomain.BaseDirectory;
// this scripts runs without params
python_script_name = #"myPythonScript.py -sd 01/01/2015 -ed 05/09/2017";
startInfo.Arguments="\""+appEXE+ "Python\\"+ python_script_name + "\"";
startInfo.UseShellExecute = false;
startInfo.RedirectStandardOutput = true;
startInfo.CreateNoWindow = true;
startInfo.RedirectStandardError = true;
using (Process process = Process.Start(startInfo))
{
using (StreamReader reader = process.StandardOutput)
{
string result = reader.ReadToEnd();
//MessageBox.Show("Normal results"+result);
Debug.WriteLine(result);
}
process.WaitForExit();
// This will show error: no such file or directory
MessageBox.Show("Errors"+process.StandardError.ReadToEnd());
GC.Collect();
Try these lines out:
string scriptPath = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Python", "myPythonScript.py")
startInfo.Arguments = "\"" + scriptPath + "\"" + " -sd 01/01/2015 -ed 05/09/2017"
I think you had an issue with quotation marks.

Read from an external program/console

I have a problem, I need to execute a console program and I have to show the output information of that console on my program. I have a string variable called "result" that have to storage that information, but is always null and I don't know why. Can anyone help me? I put the code below:
Process p = new Process();
p.StartInfo.FileName = "python";
p.StartInfo.Arguments = #"C:\Users\xxx\xxx\xxx\xxx_\xxx yyy\zzz.py " + path;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.UseShellExecute = false;
p.Start();
StreamReader sr = p.StandardOutput;
p.WaitForExit();
string result = sr.ReadToEnd();
sr.Close();
textBox1.Text = result;
On the console, I recieve 8382 JGK, for example, but my result variable is always "".
You could try something like this
StreamReader sr = p.StandardOutput;
p.WaitForExit();
char[] result = new char[p.Length]; //or sr.BaseStream.Length
sr.Read(result,0,(int)p.Length); // again or sr.BaseStream.Length
And see if result array contains anything.
I solve it! The problem was on the file's path. I have to put it on the same folder as the ".py" file and it works fine. I add the correct piece of code:
string python = #"C:\xxx\python.exe";
string myPythonApp = "program.py";
string x = #"file.jpg";
ProcessStartInfo myProcessStartInfo = new ProcessStartInfo(python);
myProcessStartInfo.UseShellExecute = false;
myProcessStartInfo.RedirectStandardOutput = true;
myProcessStartInfo.Arguments = myPythonApp + " " + x;
Process myProcess = new Process();
myProcess.StartInfo = myProcessStartInfo;
myProcess.StartInfo.CreateNoWindow = true;
myProcess.Start();
StreamReader myStreamReader = myProcess.StandardOutput;
string myString = myStreamReader.ReadLine();
myProcess.WaitForExit();
myProcess.Close();
textBox1.Text = myString;

Running exe with parameters doesn't work

var p = Process.Start(#"c:\PsTools\PsExec.exe", #"C:\Windows\System32\notepad.exe");
var err = p.StandardError.ReadToEnd();
var msg = p.StandardOutput.ReadToEnd();
lblStatusResponse.Text = "Err: " + err + "Msg: " + msg;
Why is my code not working?
I getting error:
System.InvalidOperationException: StandardError has not been redirected.
But when I add following:
p.StartInfo.RedirectStandardError = true;
var p = Process.Start(#"c:\PsTools\PsExec.exe", #"C:\Windows\System32\notepad.exe");)
it still gets the same error.
The main problem is that I wanna execute a exe with arguments, but I can't get it to work.
The following code generates a new p, this ignoring the settings you change in the previous instance:
var p = Process.Start(#"c:\PsTools\PsExec.exe", #"C:\Windows\System32\notepad.exe");)
So it doesn't really matter whether you initialize p like this
p.StartInfo.RedirectStandardError = true;
or not.
What you need to do
You need to create a ProcessStartInfo object, configure it and then pass it to Process.Start.
ProcessStartInfo p = new ProcessStartInfo(#"c:\PsTools\PsExec.exe", #"C:\Windows\System32\notepad.exe");
p.UseShellExecute = false;
p.RedirectStandardError = true;
p.RedirectStandardOutput = true;
Process proc = Process.Start(p);
var err = proc.StandardError.ReadToEnd();
var msg = proc.StandardOutput.ReadToEnd();
Taken from MSDN: https://msdn.microsoft.com/en-us/library/system.diagnostics.process.standardoutput(v=vs.110).aspx
The StandardOutput stream has not been defined for redirection; ensure ProcessStartInfo.RedirectStandardOutput is set to true and ProcessStartInfo.UseShellExecute is set to false.
So remember to set those flags as instructed by MS.
Process proc = new Process();
proc.StartInfo.FileName = "cmd.exe";
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.RedirectStandardError = true;
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.Arguments = "/C " + command; //Enter your own command
proc.Start();
string output =proc.StandardOutput.ReadToEnd();
I know this is not the same code you have but this is was the only working code I have , that will run external command/process in C# , and return all of it output/errors to the application main window
public void Processing()
{
//Create and start the ffmpeg process
System.Diagnostics.ProcessStartInfo psi = new ProcessStartInfo("ffmpeg")
{ // this is fully command argument you can make it according to user input
Arguments = "-y -i '/mnt/Disk2/Video/Antina03.jpg' pp.mp4 ",
RedirectStandardOutput = true,
WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden,
UseShellExecute = false,
RedirectStandardError=true,
RedirectStandardInput=true
};
System.Diagnostics.Process ischk;
ischk = System.Diagnostics.Process.Start(psi);
ischk.WaitForExit();
////Create a streamreader to capture the output of ischk
System.IO.StreamReader ischkout = ischk.StandardOutput;
ischk.WaitForExit();
if (ischk.HasExited) // this condition very important to make asynchronous output
{
string output = ischkout.ReadToEnd();
out0 = output;
}
/// in case you got error message
System.IO.StreamReader iserror = ischk.StandardError;
ischk.WaitForExit();
if (ischk.HasExited)
{
string output = iserror.ReadToEnd();
out0 = output;
}
}
if you want to run this process just call the function Processing() BTW out0 are global variable so it can use out the function .
credit
I'm using MonoDevlop "C# devloping tool on Linux " and I get the output this way :-
public MainWindow() : base(Gtk.WindowType.Toplevel)
{
Build();
Processing();
textview2.Buffer.Text = out0;
}

Spaces in command line argument not working

I have requirement to execute the command line arguments. If file path contains the Spaces it doesn’t work properly. It returns the error file not found. The program is given below.
public void Method()
{
string docFile = #"C:\Test Document1.doc";
string docxFile = #"C:\Test Document1.docx";
string file = #"C:\doc2x_r649 (1)\doc2x_r649\doc2x.exe";
ExecuteCommand(file, string.Format(docFile + " -o " + docxFile));
}
public static string ExecuteCommand(string file, string command)
{
String result;
try
{
//Create a new ProcessStartInfo
System.Diagnostics.ProcessStartInfo procStartInfo = new System.Diagnostics.ProcessStartInfo();
//Settings
procStartInfo.UseShellExecute = false;
procStartInfo.CreateNoWindow = false;
procStartInfo.RedirectStandardOutput = true;
procStartInfo.FileName = file;
procStartInfo.Arguments = command;
//Create new Process
System.Diagnostics.Process proc = new System.Diagnostics.Process();
//Set ProcessStartInfo
proc.StartInfo = procStartInfo;
//Start Process
proc.Start();
//Wait to exit
proc.WaitForExit();
//Get Result
result = proc.StandardOutput.ReadToEnd();
//Return
return result;
}
catch
{
}
return null;
}
If file path doesn't contains spaces it works properly.
Have you tried adding quotes to your paths?
ExecuteCommand(file, string.Format("\"" + docFile + "\" -o \"" + docxFile + "\""));
Try this
ExecuteCommand(file, string.Format("\"{0}\" -o \"{1}\"",docFile , docxFile));

How can i get build/rebuild realtime output

I'm making Visual Studio package where i start devenv.exe and try to build other solution.I need to get building output in realtime, so user can see buiding progress(output), but i don't know how to do it and if it's even possible.
I tried such way :
string rebuildLog = string.Empty;
string logFileName = System.IO.Path.GetTempFileName();
System.Diagnostics.ProcessStartInfo psi = new System.Diagnostics.ProcessStartInfo();
psi.FileName = #"devenv.exe";
psi.Arguments = "\"" + config.DmsPath + "\"" + #" /rebuild" + " Release|x64 " +" /out " + logFileName;
System.Diagnostics.Process process = new System.Diagnostics.Process();
process.StartInfo = psi;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.UseShellExecute = false;
process.Start();
while (!process.StandardOutput.EndOfStream)
{
string line = process.StandardOutput.ReadLine();
MessageBox.Show(line); // just to see if it works. It should go to log form
}
rebuildLog = GetRebuildLog(logFileName);
And rebuildLog has output.
Can anybody help ?
I found answer.
devenv.exe doesn't write simple console output, so i had to change
psi.FileName = #"devenv.exe"; to psi.FileName = #"devenv.com"; and it worked.

Categories