It's a little bit complicated problem. I have tried probably everything and still no working. I run WinForm application from I run CMD and next run another app(console application) on cmd. It's working on /c START xyz but when app finished CMD always is closing. I want to pause this window.
ProcessStartInfo processInfo = new ProcessStartInfo {
FileName = "cmd.exe",
WorkingDirectory = Path.GetDirectoryName(YourApplicationPath),
Arguments = "/K START " + cmdparametr,
RedirectStandardOutput = true,
RedirectStandardInput = true,
RedirectStandardError = true,
CreateNoWindow = false,
UseShellExecute = false,
WindowStyle = System.Diagnostics.ProcessWindowStyle.Normal,
};
Process p = new Process {
StartInfo = processInfo
};
p.Start();
int ExitCode;
p.WaitForExit();
// *** Read the streams ***
string output = p.StandardOutput.ReadToEnd();
string error = p.StandardError.ReadToEnd();
ExitCode = p.ExitCode;
MessageBox.Show("output>>" + (String.IsNullOrEmpty(output) ? "(none)" : output));
MessageBox.Show("error>>" + (String.IsNullOrEmpty(error) ? "(none)" : error));
MessageBox.Show("ExitCode: " + ExitCode.ToString(), "ExecuteCommand");
p.Close();
ReadStream is working when I add argument: START /b but I think it's not important.
WaitForExit() doesn't work.
Is it possible to pause application through command maybe like this:
/k start xyz.exe & PAUSE?
My app is console application!
You can use the pause-command inside C# if you want:
I use it as follows:
Solution №1:
//optional: Console.WriteLine("Press any key ...");
Console.ReadLine(true);
Solution №2: (Uses P/Invoke)
// somewhere in your class
[DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl, SetLastError=true)]
public static extern int system(string command);
public static int Main(string[] argv)
{
// your code
system("pause"); // will automaticly print the localized string and wait for any user key to be pressed
return 0;
}
EDIT: you can create a temporary batch file dynamically and execute it, for example:
string bat_path = "%temp%/temporary_file.bat";
string command = "command to be executed incl. arguments";
using (FileStream fs = new FileStream(bat_path, FileMode.OpenOrCreate, FileAccess.Write, FileShare.Read))
using (StreamWriter sw = new StreamWriter(fs, Encoding.Default))
{
sw.WriteLine("#echo off");
sw.WriteLine(command);
sw.WriteLine("PAUSE");
}
ProcessStartInfo psi = new ProcessStartInfo() {
WorkingDirectory = Path.GetDirectoryName(YourApplicationPath),
RedirectStandardOutput = true,
RedirectStandardInput = true,
RedirectStandardError = true,
CreateNoWindow = false,
UseShellExecute = false,
WindowStyle = System.Diagnostics.ProcessWindowStyle.Normal
};
Process p = new Process() {
StartInfo = psi;
};
p.Start();
int ExitCode;
p.WaitForExit();
// *** Read the streams ***
string output = p.StandardOutput.ReadToEnd();
string error = p.StandardError.ReadToEnd();
ExitCode = p.ExitCode;
MessageBox.Show("output>>" + (String.IsNullOrEmpty(output) ? "(none)" : output));
MessageBox.Show("error>>" + (String.IsNullOrEmpty(error) ? "(none)" : error));
MessageBox.Show("ExitCode: " + ExitCode.ToString(), "ExecuteCommand");
p.Close();
File.Delete(bat_path);
For preventing the close of a Console Application you could use :
Console.ReadLine();
It would wait for for any key and would not close immediately.
Do not include START command, use something like this
processInfo.Arguments = "/K " + your_console_app_exe_path_and_args;
Make sure to enclose with double quotes where needed.
Related
I have written a console application to call the AZcopy tool programmatically, but I was not able to call azcopy tool. Can you please redirect me the workable source ? I have downloaded azcopy_windows_amd64_10.12.1 and put azcopy.exe into C:\Windows\System32\azcopy.exe location
static void Main(string[] args)
{
string strCmdText = #"AzCopy.exe sync ""D:\temp"" ""https://myhubforazcopy.blob.core.windows.net/myhubforazcopy1?sp=racwdl&st=2021-09-05T17:19:11Z&se=2021-09-06T01:19:11Z&spr=https&sv=2020-08-04&sr=c&sig=MAraJ0PxqJMDdYuWzrOUEwYda%2BkXEukP%2Fs%3D"" --destination-delete=true";
CallProcess(strCmdText);
}
public static void CallProcess(string strCmdText)
{
//C:\Windows\System32\azcopy.exe
var process = new Process();
ProcessStartInfo startInfo = new ProcessStartInfo
{
FileName = #"C:\Windows\System32\cmd.exe",
RedirectStandardInput = true,
RedirectStandardOutput = true,
Arguments = strCmdText,
UseShellExecute = false,
CreateNoWindow = false,
WorkingDirectory = #"D:\AzCopy\bin\Debug\"
};
process.StartInfo = startInfo;
process.Start();
process.StandardInput.Flush();
process.StandardInput.Close();
process.WaitForExit();
Console.WriteLine(process.StandardOutput.ReadToEnd());
}
Starting cmd with the program you want to execute as the argument doesn't actually runt that program, you'll need to pass the entire argument (your program) after the /c flag, like so:
string strCmdText = #"/c AzCopy.exe sync ""D:\temp"" ...
Make sure that AzCopy is in your PATH or specify the precise path to it
But it would be better if you just directly run AzCopy instead of starting a command prompt which then starts AzCopy, this would be done like so:
// Notice how the 'azcopy' at the start is gone
var arguments = #"""D:\temp"" ""https://myhubforazcopy.blob ..."
var process = new Process();
ProcessStartInfo startInfo = new ProcessStartInfo
{
FileName = #"C:\Windows\System32\azcopy.exe",
RedirectStandardInput = true,
RedirectStandardOutput = true,
Arguments = arguments,
UseShellExecute = false,
CreateNoWindow = false,
WorkingDirectory = #"D:\AzCopy\bin\Debug\"
};
Solution :
static void Main(string[] args)
{
string strCmdText = #"/c azcopy.exe sync ""D:\temp"" ""https://myhubforazcopy.blob.core.windows.net/myhubforazcopy1?sp=racwdl&st=2021-09-05T17:19:11Z&se=2021-09-06T01:19:11Z&spr=https&sv=2020-08-04&sr=c&sig=MAraJ0PxqJMDdYuWzrOUEwYda%2BkXEukP%2Fs%3D"" --delete-destination=true";
CallProcess(strCmdText);
}
public static void CallProcess(string strCmdText)
{
var process = new Process();
ProcessStartInfo startInfo = new ProcessStartInfo
{
FileName = #"cmd.exe",
RedirectStandardInput = true,
RedirectStandardOutput = true,
Arguments = strCmdText,
UseShellExecute = false,
CreateNoWindow = false,
WorkingDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)
};
process.StartInfo = startInfo;
process.Start();
process.StandardInput.Flush();
process.StandardInput.Close();
process.WaitForExit();
Console.WriteLine(process.StandardOutput.ReadToEnd());
}
I have a created a small app that would download and Install Python and then install a list of Python Libraries using pip.
I am using the Process.WaitForExit() method to make sure that the installation of Python is complete before I begin the libraries installation. Below is my code for installing Python
public void installPython()
{
Process process = new Process();
process.StartInfo.FileName = #"C:\Python36\python-3.6.3-amd64.exe";
process.Start();
process.WaitForExit();
}
Below is the code which then launches cmd and executes the pip command :
public void installLibraries()
{
int exitCode;
string command = "pip install -r requirements.txt";
ProcessStartInfo processInfo;
Process process;
processInfo = new ProcessStartInfo("cmd.exe", "/c " + command);
processInfo.CreateNoWindow = true;
processInfo.UseShellExecute = false;
processInfo.RedirectStandardError = true;
processInfo.RedirectStandardOutput = true;
process = Process.Start(processInfo);
process.WaitForExit();
string error = process.StandardError.ReadToEnd();
exitCode = process.ExitCode;
Console.WriteLine("output>>" + (String.IsNullOrEmpty(output) ? "(none)" : output));
Console.WriteLine("error>>" + (String.IsNullOrEmpty(error) ? "(none)" : error));
Console.WriteLine("ExitCode: " + exitCode.ToString(), "ExecuteCommand");
process.Close();
}
Then in the Main method I call the installPython method and then the installLibraries method
Unfortunately the compiled .exe isn't following the correct order. When I run the command from the cmd after browsing to the directory, I get the error :
output>>(none)
error>>'pip' is not recognized as an internal or external command,
operable program or batch file.
Is there a mistake in how I am using the Process functions?
This is Start process and wait until finished.
public static void StartProcessAndWait(string processFile, string arguments, string workingDirectory)
{
var proc = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = processFile,
Arguments = arguments,
UseShellExecute = false,
RedirectStandardOutput = true,
CreateNoWindow = true,
RedirectStandardError = true,
WorkingDirectory = workingDirectory
}
};
proc.Start();
var _ = ConsumeReader(proc.StandardOutput);
// ReSharper disable once RedundantAssignment
_ = ConsumeReader(proc.StandardError);
async Task ConsumeReader(TextReader reader)
{
string text;
while ((text = await reader.ReadLineAsync()) != null)
Console.WriteLine(text);
}
proc.WaitForExit(30000);
}
I'm trying to run the following code in my C# WPF application. Whenever I use something like dir (I should probably mention the output is the directory of my working folder in Visual Studio, not System32), it allows it. However, if I use systeminfo or set the working directory to C:\Windows\System32, it hangs...
MessageBox.Show("STARTED");
var processInfo = new ProcessStartInfo("cmd.exe", "/c systeminfo") {
CreateNoWindow = true,
UseShellExecute = false,
RedirectStandardError = true,
RedirectStandardOutput = true,
//WorkingDirectory = #"C:\Windows\System32\"
};
// *** Redirect the output ***
Process process = Process.Start(processInfo);
if (process == null) return false;
process.WaitForExit();
MessageBox.Show("Done");
string output = process.StandardOutput.ReadToEnd().ToLower();
string error = process.StandardError.ReadToEnd();
int exitCode = process.ExitCode;
MessageBox.Show(output);
MessageBox.Show(error);
MessageBox.Show(exitCode.ToString(CultureInfo.InvariantCulture));
Any ideas?
Just tried this and works as expected.
Of course you need to read the redirected output before the process closes.
var processInfo = new ProcessStartInfo("cmd.exe", "/c systeminfo")
{
CreateNoWindow = true,
UseShellExecute = false,
RedirectStandardError = true,
RedirectStandardOutput = true,
WorkingDirectory = #"C:\Windows\System32\"
};
StringBuilder sb = new StringBuilder();
Process p = Process.Start(processInfo);
p.OutputDataReceived += (sender, args) => sb.AppendLine(args.Data);
p.BeginOutputReadLine();
p.WaitForExit();
Console.WriteLine(sb.ToString());
how can i make my console application window to behave like a command prompt window and execute my command line arguments?
This should get you started:
public class Program
{
public static void Main(string[] args)
{
var proc = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = "cmd.exe",
CreateNoWindow = true,
UseShellExecute = false,
RedirectStandardInput = true,
RedirectStandardOutput = true,
RedirectStandardError = true
}
};
proc.Start();
new Thread(() => ReadOutputThread(proc.StandardOutput)).Start();
new Thread(() => ReadOutputThread(proc.StandardError)).Start();
while (true)
{
Console.Write(">> ");
var line = Console.ReadLine();
proc.StandardInput.WriteLine(line);
}
}
private static void ReadOutputThread(StreamReader streamReader)
{
while (true)
{
var line = streamReader.ReadLine();
Console.WriteLine(line);
}
}
}
The basics are:
open cmd.exe process and capture all three streams (in, out, err)
pass input from outside in
read output and transfer to your own output.
The "Redirect" options are important - otherwise you can't use the process' respective streams.
The code above is very basic, but you can improve on it.
I believe you are looking for this
var command = "dir";
System.Diagnostics.ProcessStartInfo procStartInfo = new System.Diagnostics.ProcessStartInfo("cmd", "/c " + command);
procStartInfo.RedirectStandardOutput = true;
procStartInfo.UseShellExecute = false;
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.StartInfo = procStartInfo;
proc.Start();
string result = proc.StandardOutput.ReadToEnd();
Console.WriteLine(result);
I have an application where i am trying to run a python from a c# application. i have tried creating the python runtime environment and run the code, but as my python code is importing some modules from another python file it throws an exception (import exception). i have tried the following code:
var ipy = Python.CreateRuntime();
dynamic test = ipy.UseFile(#"file path");
test.Simple();
Console.Read();
I hvae another idea of running it through cmd prompt, but i don't know how do it. i want open to cmd.exe and execute the python file and i want it such that the user enters the filename in c# aplication and on clicking the run button the code is executed through cmd.exe and the output is again shown in c# application.
Any other suggestions are also welcome.
That would do the job: the following example runs cmd which runs TCL script (that wat I have installed on my computer) you only need to replace the command to run Python and add your script file.
Pay attention to the " & exit" comming after your script file name - this makes the cmd exit after your script exits.
string fileName = "C:\\Tcl\\example\\hello.tcl";
Process p = new Process();
p.StartInfo = new ProcessStartInfo("cmd", "/K tclsh " + fileName + " & exit")
{
RedirectStandardOutput = true,
UseShellExecute = false,
CreateNoWindow = true
};
p.Start();
string output = p.StandardOutput.ReadToEnd();
p.WaitForExit();
Console.WriteLine(output);
Console.ReadLine();
[Update]
After Python installation and testing, that would be the code to run python script with cmd:
string fileName = #"C:\Python27\example\hello_world.py";
Process p = new Process();
p.StartInfo = new ProcessStartInfo("cmd", "/K " + fileName + " & exit")
{
RedirectStandardOutput = true,
UseShellExecute = false,
CreateNoWindow = true
};
p.Start();
string output = p.StandardOutput.ReadToEnd();
p.WaitForExit();
Console.WriteLine(output);
Console.ReadLine();
Also you can do the same without the CMD process:
string fileName = #"C:\Python27\example\hello_world.py";
Process p = new Process();
p.StartInfo = new ProcessStartInfo(#"C:\Python27\python.exe", fileName )
{
RedirectStandardOutput = true,
UseShellExecute = false,
CreateNoWindow = true
};
p.Start();
string output = p.StandardOutput.ReadToEnd();
p.WaitForExit();
Console.WriteLine(output);
Console.ReadLine();
I cannot test it personally at the moment, but I found some people using Python.CreateEngine() in their code, example:
Microsoft.Scripting.Hosting.ScriptEngine engine =
IronPython.Hosting.Python.CreateEngine();
This line was taken from this SO question.
You can also check this article with example class using python code. It also uses Python.CreateEngine().
i have tried the following code and it seems to solve my problem:
Process p = new Process();
string cmd = #"python filepath & exit";
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.RedirectStandardInput = true;
p.Start();
StreamWriter myStreamWriter = p.StandardInput;
myStreamWriter.WriteLine(cmd.ToString());
myStreamWriter.Close();
string output = p.StandardOutput.ReadToEnd();
p.WaitForExit();
Console.ReadLine();