I am writing a windows forms application in C#
I have a Process Object which runs a cmd command and returns it's output.
Process Pro = new Process();
Pro.StartInfo.FileName = "cmd.exe";
Pro.StartInfo.Arguments = "<Dos Command here>";
Pro.StartInfo.CreateNoWindow = true;
Pro.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
Pro.StartInfo.RedirectStandardOutput = true;
Pro.StartInfo.UseShellExecute = false;
Pro.Start();
Which works fine! However if the output of the command is not ASCII(in my case Greek), the Output are random symbols. Surely an encoding problem.
If i run the same code on a console application everything runs smoothly.
I tried reading the Base stream as UTF-8, but no luck!
System.IO.StreamReader Rdr = new System.IO.StreamReader(Pro.StandardOutput.BaseStream, Encoding.UTF8);
Is there any way to read the output properly in a winform application?
Thnx!
The real solution is base on this:
unicode-characters-in-windows-command-line-how
check here:
Wiki code page
for the code page you need.
you can also do an ugly hack, writing the command to a batch file (f.e foo.bat)
then running it as foo.bat > log.txt
then you can read the output from log.txt.
Related
I have multiple .gz files in a directory (2 or more), with at least one file missing the end of file marker. Our C# process is unable to read the file with missing end of file, but since they are coming from a third party we do not have control over how they are created.
As such, we've been running the following Linux command manually:
cat file1.gz file2.gz > newFile.gz
In order to automate this, I am looking for a way to leverage the Process functionality in C# to trigger the same command, but this would only be available in Cygwin or some other Linux shell. In my example, I'm using git bash but it could be Powershell or Cygwin or any other available Linux shell that runs on a Windows box.
The following code does not fail, but it does not work as expected. I am wondering if anyone has recommendations about how to do this or any suggestions on a different approach to consider?
Assume that the working directory is set and initialized successfully, so the files exist where the process is run from.
Process bashProcess = new Process();
bashProcess.StartInfo.FileName = #"..\Programs\Git\git-bash.exe";
bashProcess.StartInfo.UseShellExecute = false;
bashProcess.StartInfo.RedirectStandardInput = true;
bashProcess.StartInfo.RedirectStandardOutput = true;
bashProcess.Start();
bashProcess.StandardInput.WriteLine("cat file1.gz file2.gz > newFile.gz");
bashProcess.StandardInput.WriteLine("exit");
bashProcess.StandardInput.Flush();
.
.
.
bashProcess.WaitForExit();
My expectation is that newFile.gz is created
I was able to find a solution to my problem using a DOS command, and spawning a cmd Process from CSharp.
My code now looks like this, avoids having to launch a linux-based shell from Windows, and the copy command in windows does the same thing as cat:
Process proc = new Process();
proc.EnableRaisingEvents = false;
proc.StartInfo.FileName = "cmd";
proc.StartInfo.Arguments = #"/C pushd \\server\folder && copy *.txt.gz /b
combined.gz";
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.RedirectStandardError = true;
proc.StartInfo.UseShellExecute = false;
proc.Start();
proc.WaitForExit();
System.Threading.Thread.Sleep(2000);
string line = proc.StandardOutput.ReadLine();
while (line != null)
{
output.Append(line);
line = proc.StandardOutput.ReadLine();
}
First of all I do not know if it is a bad practice to call python script from c# so if this is the case please tell me.My current problem is as follows.
MY c# code only runs the python script partially....
means (python script create only 4 files when it is supposed to create 10 files)
But When I run my script from cmd in windows I see complete functionality....
Another thing I saw is when I stop my Visual Studio(2013) I see the complete functionality
I am calling the python script(main.py) from c# like this...
public JsonResult FetchscrapyDataUrl(String website)
{
ProcessStartInfo start = new ProcessStartInfo();
start.FileName = #"C:\ProgramData\Anaconda3\python.exe";
start.Arguments = #"C:\Users\PycharmProjects\scraping_web\scrape_info\main.py";
//this is path to .py file from scrapy project
start.CreateNoWindow = false; // We don't need new window
start.UseShellExecute = false; // Do not use OS shell
//start.RedirectStandardOutput = true;// Any output, generated by application will be redirected back
start.RedirectStandardError = true; // Any error in standard output will be redirected back (for example exceptions)
Console.WriteLine("Python Starting");
start.RedirectStandardOutput = true;
using (Process process = Process.Start(start))
{
using (StreamReader reader = process.StandardOutput)
{
string stderr = process.StandardError.ReadToEnd(); // Here are the exceptions from our Python script
string result = reader.ReadToEnd(); // Here is the result of StdOut(for example: print "test")
Console.Write(result);
}
}
}
Why I am getting complete script functionality when I stop in Visual Studio(2013)??
I dont understand you motivation behind this. But why dont you use IronPython which is excellent addition to the .NET Framework, providing Python developers with the power of the .NET framework.
I'm currently creating an application in C# that allows you to create a server and manage it easily, to do this it uses batch files to run said servers. It works by creating batch files and using those to run the server. (Java by the way).
So, what I'm wondering is if it's possible to grab the output from the console and rather than dumping it in a textbox and closing the console like the code below does, I need it to continually post any output from the console without closing and without spamming loads of consoles open (tried using a timer).
Process myProcess = new Process();
ProcessStartInfo myProcessStartInfo =
new ProcessStartInfo(batchfilelocation);
myProcessStartInfo.UseShellExecute = false;
myProcessStartInfo.RedirectStandardOutput = true;
myProcess.StartInfo = myProcessStartInfo;
myProcess.Start();
StreamReader myStreamReader = myProcess.StandardOutput;
// Read the standard output of the spawned process.
string myString = myStreamReader.ReadToEnd();
textBox1.Text = textBox1.Text + myString;
myProcess.Close();
I'm also wondering if it would be possible to allow input from a windows forms control such as a button that would execute a command by entering it in the console and pressing enter for example. Or a textbox that allows you to do the same thing.
Thanks!
You don't need a TextBox control to store a string. Just use a string variable instead.
string concatenatedString = null;
concatenatedString += myStreamReader.ReadToEnd();
Secondly, you can do this without creating a console window. The code below will allow your program to run without seeing a ton of console windows popup.
myProcessStartInfo.CreateNoWindow = true;
Envrionment: .Net 2.0, Windows 2003, 64bit
I am trying to move the website from old server to new server, and below code is not working anymore after moving the codes:
System.Diagnostics.ProcessStartInfo psi = new
System.Diagnostics.ProcessStartInfo("cmd.exe");
psi.UseShellExecute = false;
psi.RedirectStandardOutput = true;
psi.RedirectStandardInput = true;
psi.RedirectStandardError = true;
// Start the process
System.Diagnostics.Process proc = System.Diagnostics.Process.Start(psi);
System.IO.StreamReader strm = proc.StandardError;
System.IO.StreamReader sOut = proc.StandardOutput;
// Attach the in for writing
System.IO.StreamWriter sIn = proc.StandardInput;
sIn.WriteLine(exec);
strm.Close();
sIn.WriteLine("EXIT");
proc.Close();
// Read the sOut to a string.
string results = sOut.ReadToEnd().Trim();
// Close the io Streams;
sIn.Close();
sOut.Close();
It seems as the system does not allow to run none of .exe. The code was working properly on previous server, so I am guessing it is some types of system config issue. I found similar issue on here: Foo.cmd won't output lines in process (on website)
but I did not understand the part "create a new user with privileges to execute batch scripts and select that user as the AppPool user in IIS".I know how to create a new user, but was not able to figure out the way giving a permission to the user to execute .exe or batch files.
Any advice would be helpful.
Thank you,
It could be a .NET Trust level on the new server. Try setting the Trust level in IIS manager to "Full" for that application.
I had C# console app, which runs another Borland C console app. It worked okay.
But after I remake the first app to WinForm app, I can't get output from Borland C console app.
Code is here:
Process p = new Process();
p.StartInfo.CreateNoWindow = true;
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.FileName = name1;
p.Start();
StreamReader sr = p.StandardOutput;
progOutput = sr.ReadToEnd();
//progOutput = p.StandardOutput.ReadToEnd();
p.WaitForExit();
The string progOutput is empty. I get the same result if I use line
progOutput = p.StandardOutput.ReadToEnd(); instead of StreamReader
Borland C console app really started and created it's output files normally.
But it's output disappeared in WinForm app.
As I said this code worked okay in C# console app,
but does not work now in C# Windows Form app.
BTW, if I run C# console app in WinForm app, output is okay.
Somehing wrong with Borland C output?
But it worked when I ran Borland C app in C# console app.
So I am puzzled.
Thanks
In some scenarios I found beneficial to launch executables indirectly like so..
p.StartInfo.FileName = "cmd";
p.StartInfo.Arguments = "/C " + name1;
..especially when having output redirect issues. But you say it worked as a console app?!
check
var errorOut = p.StandardError.ReadToEnd();
you might get output as StandardError. You can find many questions related to this, we expect output from StandardOutput but it redirect to StandardError.