Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

using command line functions within C#, and retrieving the output

Status
Not open for further replies.

Vormav

Programmer
Jun 21, 2002
12
US
After finally getting completely fed up with the standard windows command prompt, I've taken it upon myself to start trying to build a quick and simple alternative to one - an alternative that keeps all of the functions intact (so I shouldn't be rewriting any of them), while just giving it a reasonable interface. It seems to me that the easiest way to do that is by making use of what's already there, with direct calls to existing command line tools. Retrieve the output that a command prompt window would see, show it within the new, not-quite-so-woefully-inadequate interface, done.

So far, I've been able to get a hint of this working with the following code:
Code:
			Process p = new Process(); 
			p.StartInfo.UseShellExecute = false;        
			p.StartInfo.RedirectStandardOutput = true; 
			p.StartInfo.Arguments="/some arguements"; 
			p.StartInfo.FileName =  "someexecutable.exe";
			p.StartInfo.CreateNoWindow=true;            
			p.Start();                                                 
			string output = p.StandardOutput.ReadToEnd(); 
			p.WaitForExit();                                       
			richTextBox1.Text = output;

This *works*, but brought up a couple of problems:

First of all, this is great if I'm just going to be making calls to executables, which is probably what'll be happening most of the time, but doesn't work for commands that don't run directly off of executables - like dir, md, and other similar commands.
Now, I'm sure that someone is going to suggest that I just write my own variants of these commands in C#, making use of the file I/O functions built into the system libraries of C#. But do consider that recreating these functions in their entirety is just a *little bit* more complicated than finding out how to make calls to the existing commands.
I did try making a call to cmd.exe with arguements /c dir, but each attempt at passing these commands through like that has caused the app to crash.
So, is there any direct way to make calls to those commands in C#? I've also tried using batch files to get around this problem, but I get "file cannot be found" errors whenever I try tio load a .bat file.

Problem number two comes down to how the results are returned, and is probably a major deciding factor on how feasible this whole program really is. Let's say I'm pinging google.com through this app: regardless of whether or not I have that "p.WaitForExit();" line in there, my text box won't be getting updated until the entire ping process has completed. Of course, ideally I'd be getting updates in my textbox after each individual ping result. Take another example: Let's say I'm doing some long (2-hour+) batch renderings with mental ray or some other renderer. Obviously, I'm going to want to periodically see the output statements that the renderer prints to the shell to give me an idea of how far along in the rendering I am. But in the app's current stage, I'd have to wait for the entire rendering to finish before I could see anything about its progress.
So, I really just need a way to retrieve output from the file being run whenever that file gives output, not just when it is finished running. Is this possible?


Thanks!
 
p.Start();

while (!p.HasExited)
{
string output = p.StandardOutput.ReadLine();
myConsole.WriteLine(output);
}


No more WaitForExit();
 
Hey, thanks. That's one problem down. :)
There is another problem that I didn't really consider, though: Using the start() method to make a call to an executable that requests user input (take cygwin as a quick example). Can't say I'm too clear on how to deal with that.
 
maybe create a temporary batch file that you execute through cmd.exe (windows 2k and higher).
 
Modified for VB, but it shows you what you need:

Code:
		Dim p As Process = New Process()
		p.StartInfo.UseShellExecute = False
		p.StartInfo.RedirectStandardOutput = True
		[b]p.StartInfo.Arguments = "/c dir c:"
		p.StartInfo.FileName = "cmd.exe"[/b]
		p.StartInfo.CreateNoWindow = True
		p.Start()
		Dim output As String = p.StandardOutput.ReadToEnd()
		p.WaitForExit()
		RichTextBox1.Text = output

cmd.exe /c

starts cmd.exe and closes it after completion

Hope this helps.

[vampire][bat]
 
Hey, sorry for a late reply. Been busy. But thanks for the tip. I actually tried something very similar before that was locking everything up, but this seems to being the trick.

As for command line programs that request user input (like Cygwin), I have noticed that I am able to supply the command line application with further input just by using the process' WriteLine() method. And I could potentially use the HasExited event to decide whether or not I want my application to accept further user input to write to the process (if the process hasn't exited, you might assume that it's waiting for user input).
The problem with this is that I don't have any way of differentiating between these cases, and cases where the application is just waiting to complete some process before returning output and freeing up the command prompt. Command line rendering is a good example of this -- a process might be running for hours on end before exiting, and not accepting any user input during any of this time.
So, is there any sure way to tell if the program is waiting for input or not?

Thanks!
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top