in c#, can't suppress every line of a process - c#

I'm trying to read the output of a process to string. For some reason, it sort of looks like the one line in the middle of the output seems to get outputted (ie, it's displayed on the screen, and NOT saved to the string).
string strOutput = "";
Process process = new Process();
process.StartInfo.FileName = "nslookup";
process.StartInfo.Arguments = "-type=mx uic.edu";
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.Start();
strOutput = process.StandardOutput.ReadToEnd();
process.WaitForExit();
Console.WriteLine("xxxxxxxxxxxxxxxxxxx");
Console.WriteLine(strOutput);
Console.WriteLine("yyyyyyyyyyyyyyyyyyy");
I get output that looks like this:
Non-Authoritative answer:
xxxxxxxxxxxxxxxxxxxx
Server: aaa.myserver.com
Address: 111.222.111.222
uic.edu MX preference = 10, mail exchanger - ...
...
yyyyyyyyyyyyyyyyyyyy
When I run the command via command line, "Non-Authoritative answer:" comes after "Address: ..."
Can someone explain why it's outputted, and not stored as part of the string? I'm probably missing something obvious, but I'm boggled.
Thanks

That line is probably going to STDERR rather than STDOUT. Try redirecting standard error as well as standard output.
process.StartInfo.RedirectStandardError = true;

Related

Unity C# Encoding Type

I create simple unity application, there is button that give user print a picture. When button is clicked, it will run a command in cmd but I get this message,
'cd' is not recognized as an internal or external command,
operable program or batch file.
I search the web, it says I need to change encoding type but I have do it in Notepad++ (I change it from UTF-8 BOM to ANSI) but it still no work.
Here is my code, in case I am wrong.
string fullCommand = "rundll32 C:/WINDOWS/system32/shimgvw.dll,ImageView_PrintTo " + filePath + printerName
System.Diagnostics.Process process = new System.Diagnostics.Process();
process.StartInfo.FileName = "cmd.exe";
process.StartInfo.CreateNoWindow = false;
process.StartInfo.RedirectStandardInput = true;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.UseShellExecute = false;
process.StartInfo.Arguments = "/c " + fullCommand;
process.Start();
This is my reference
How to direct printing of photo or text using Unity without preview
I expect it to print the expected file but it do not. I hope someone can guide me. Thank you for helping.
Cheers
Kev

"The system cannot find the file specified" error on process.Start();

I am trying to get the process respond as a string so I can use it in different place in my code, this is the solution that I have so far:
const string ex1 = #"C:\Projects\MyProgram.exe ";
const string ex2 = #"C:\Projects\ProgramXmlConfig.xml";
Process process = new Process();
process.StartInfo.WorkingDirectory = #"C:\Projects";
process.StartInfo.FileName = "MyProgram.exe ";
process.StartInfo.Arguments = ex2;
process.StartInfo.Password = new System.Security.SecureString();
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
try
{
process.Start();
StreamReader reader = process.StandardOutput;
string output = reader.ReadToEnd();
}
catch (Exception exception)
{
AddComment(exception.ToString());
}
But when I'm running this I get:
"The system cannot find the file specified" error in process.Start(); without
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
The code runs fine but it just open console window and all the process response is trow there so I can't use it as string.
Does anyone know why I am getting this error or maybe a different solution to my problem?
I suspect the problem is that the filename you're specifying is relative to your working directory, and you're expecting Process.Start to look there when starting the process - I don't believe it works that way when UseShellExecute is false. Try just specifying the absolute filename of the process you want to start:
process.StartInfo.FileName = #"C:\Projects\MyProgram.exe";
Note that I've also removed the space from the end of the string you were assigning for the FileName property - it's entirely possible that was casuing the problem too.
For System32 access if you are trying to RUN an x86 Application on x64 then you must use the "Sysnative" keyword instead of "System32" in your filename.
EG: instead of:
C:\Windows\System32\whoiscl.exe
It should be:
C:\Windows\Sysnative\whoiscl.exe
Hope this helps someone

C# Redirecting process results to a text file

I've been racking my brain trying to figure out why I can not use >> (append) as a part of my p.StartInfo.Argument. When I remove ">" it works perfectly, but the moment I try to use ">" or ">>" I get a "Incorrect Parameter" error. I've gone ahead and wrote my program without > or >> and just stored the output into a string and write it to a file later. Could someone explain why ">" or ">>" would not work in this situation?
// Start the child process.
Process p = new Process();
// Redirect the output stream of the child process.
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.FileName = "attrib.exe";
startInfo.Arguments = "/S *.jpg > mypics.txt";
p.Start();
The output redirection operator > is a feature of cmd.exe, not the operating system. The naive way to use it is hence to call cmd as so:
p.StartInfo.FileName = "cmd.exe";
startInfo.Arguments = "/C \"attrib.exe /S *.jpg > mypics.txt\"";
The proper way to redirect the output, however, is to first set StartInfo.RedirectStandardOutput to true (which you did), and then pipe the output from Process.StandardOutput to the file, as so:
using(StreamWriter file = new StreamWriter("mypics.txt")) {
p.StandardOutput.CopyTo(file);
}
Or, async version:
using(StreamWriter file = new StreamWriter("mypics.txt")) {
await p.StandardOutput.CopyToAsync(file);
}
That's because > and >> are not arguments interpreted by attrib.exe, they're instructions to cmd.exe.
You could try instead something like:
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.Arguments = "/c attrib.exe /S *.jpg > mypics.txt";
Also, this is a red herring:
p.StartInfo.RedirectStandardOutput = true;
If you wanted to read the output in C# code and write the file yourself, you'd use this option. It's not helpful for using the > output redirector.
SlugFiller's solution is good but doesn't work reliably with large amounts of output. The problem is that if the process outputs too much text it hangs because the stream reaches the maximum buffer size. In other words the stream needs to be spooled out as the process runs, preventing the buffer from ever filling up.
However, there is a way to do this using a task to receive data from the output stream and spool it out in real-time.
// Start the child process.
Process p = new Process();
// Redirect the output stream of the child process.
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.FileName = "attrib.exe";
startInfo.Arguments = "/S *.jpg > mypics.txt";
p.Start();
Thread stdoutThread = new Thread(new ThreadStart(WriteStandardOutput));
stdoutThread.IsBackground = true;
stdoutThread.Name = "stdout_writer";
stdoutThread.Start();
private void WriteStandardOutput()
{
using (StreamWriter sw = File.CreateText(ConsoleLogFileFullPath))
using (StreamReader sr = p.StandardOutput)
{
for (;;)
{
string line = sr.ReadLine();
if (line == null)
break;
sw.WriteLine(textLine);
}
sw.Flush();
}
}
At some point be sure to call stdoutThread.Join() to make sure that the thread completes. I have tested this with some code that generates large amounts of output and it's still possible to overflow the buffer, or to break ReadLine() with extremely long lines, but it does work for very fast output in the order of a few thousand 80 character lines per second.

WPF + Showing ouput of bat file in TextBlock

I am trying to execute a bat file through my WPF application on a button click.
I want the output of the batch file to be displayed in a TextBlock(with vertical scroll) of WPF application.
I am able to execute a bat file using Process.Start
Here is my Code
Process process = new Process();
process.StartInfo.FileName = #"C:\bin\run.bat";
process.StartInfo.Arguments = #"-X";
process.StartInfo.WindowStyle = ProcessWindowStyle.Normal;
process.Start();
process.WaitForExit();
How to proceed further?
Thanks
I guess I will flesh out my comment with an answer. You need to redirect the output of your bat file, you do that by using Process.RedirectStandardOutput. Taking your code and the MSDN Library page's code will give you something like this.
Process process = new Process();
process.StartInfo.FileName = #"C:\bin\run.bat";
process.StartInfo.Arguments = #"-X";
process.StartInfo.WindowStyle = ProcessWindowStyle.Normal;
process.StartInfo.UseShellExecute = false; //Changed Line
process.StartInfo.RedirectStandardOutput = true; //Changed Line
process.Start();
string output = process.StandardOutput.ReadToEnd(); //Changed Line
process.WaitForExit(); //Moved Line
you need to redirect standard output to your text file using the gtr symbol ">". e.g
command>myfile.extension
and the opposite executes the commands in a file one line at a time e.g
command

Run "tf.exe status" in C# and save the result

I´m trying to create a small console app in c#. I want to run the program and save all pending changes in TFS to a .txt file. But I cant get the arguments to work. Can someone help me?
Here is my code i haved done so far:
string argument = "#tf.exe status /collection:http://tiffany:8080/tfs/ /user:* /format:detailed >c:\\Status\\Detailed.txt";
try
{
Process process = new Process();
process.StartInfo.Arguments = "#call" + " " + "C:\\Program Files (x86)\\Microsoft Visual Studio 12.0\\Common7\\Tools\\VsDevCmd.bat";
process.StartInfo.FileName = "cmd.exe";
process.StartInfo.Verb = "runas";
process.StartInfo.Arguments = argument;
process.StartInfo.CreateNoWindow = false;
process.Start();
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
Console.ReadKey();
}
aI'm not really sure that I understand what you're trying to call, exactly.
Let's assume you want to run the following command line from a C# application, as if you would call it from a command line:
tf.exe status /collection:http://tiffany:8080/tfs/ /user:* /format:detailed >c:\\Status\\Detailed.txt"
I would use this code:
string arguments = #"/C tf.exe status /collection:http://tiffany:8080/tfs/ /user:* /format:detailed >c:\\Status\\Detailed.txt";
this.process = new Process();
this.process.StartInfo.FileName = #"cmd.exe";
this.process.StartInfo.Arguments = arguments;
this.process.Start();
Edit:
If that's all your console app does, why not consider creating a batch (.BAT / .CMD) file instead of a C# application?
Instead of running a command line tool you could leverage the TFS API.
There are many articles out there, e.g. Code project article on topic
and
Sample code directly from the MSDN
I suppose you have to read standard error and output from process started:
Process process = new Process();
process.StartInfo.Arguments = #"status PATH /recursive";
process.StartInfo.FileName = "tf.exe";
process.StartInfo.CreateNoWindow = false;
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.RedirectStandardOutput = true;
process.Start();
var st = process.StandardOutput.ReadToEnd();
var err = process.StandardError.ReadToEnd();
But parsing tf output is not easy and I'd like to suggest to use TFS API as #Mare said
You do not need to create an application in C # to save in a text file. Just use the parameters (...) > [file name].txt at the end of the command.
The ">" symbol send the result of any command to a file.

Categories