How to run multiple cmd commands without reopening cmd in C#? - c#

This is my code and I'm using it in a while loop.
The cmd command changes every time. It means if I write "cd .." and in the next round of while loop if I write "dir" that's not gonna give me the previous folder items or in simpler language previous cmd closed and another one opens.
while (i < 99) {
System.Diagnostics.Process process = new
System.Diagnostics.Process();
process.StartInfo.WindowStyle =
System.Diagnostics.ProcessWindowStyle.Hidden;
process.StartInfo.FileName = "cmd.exe";
process.StartInfo.Arguments = #"/C " + lastMsg; //this line is a cmd command
process.StartInfo.UseShellExecute = false;
process.StartInfo.CreateNoWindow = true;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardInput = true;
process.Start();
string q = "";
while (!process.HasExited)
{
q += process.StandardOutput.ReadToEnd();
}
}

If you want to send all commands to the same instance of cmd, you must create this instance outside your loop, redirect the standard input, and send the commands through the standard input:
var cmdStartInfo = new ProcessStartInfo
{
FileName = "cmd",
RedirectStandardInput = true,
WindowStyle = ProcessWindowStyle.Hidden,
UseShellExecute = false,
CreateNoWindow = true,
RedirectStandardOutput = true
};
var cmdProcess = Process.Start(cmdStartInfo);
while (i < 99)
{
cmdProcess.StandardInput.WriteLine(lastMsg);
}

Related

C# How to run exe in PowerShell

I want to run mc.exe using by PowerShell as I write below.
How can I do that? I tried to add in Filename but it doesn't work.
var mcExe = #"C:\Users\developer\Desktop\Example\mc.exe ";
var proc = new System.Diagnostics.Process();
proc.StartInfo.FileName = mcExe;
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.Verb = "runas";
proc.StartInfo.Arguments = String.Format("{0}{1}{2}", "./mc alias set myCloud http://localhost:9000", "admin", "123456");
proc.Start();
Did you try set proc.StartInfo.UseShellExecute = true; ?
Because this property responsible for using powershell
Starting Powershell directly might work for you, e.g. :
using System.Diagnostics;
ProcessStartInfo startInfo = new ProcessStartInfo
{
FileName = #"powershell.exe",
Arguments = #"& 'C:\Users\developer\Desktop\Example\mc.exe' #('./mc alias set myCloud http://localhost:9000', 'admin', '123456')",
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,
CreateNoWindow = true,
Verb = "runas",
};
Process process = new Process();
process.StartInfo = startInfo;
process.Start();
string output = process.StandardOutput.ReadToEnd();
string errors = process.StandardError.ReadToEnd();

How to Execute multiple commands in Process

I have a list of a thousand items, Each of these items must be checked by the CMD.exe, With the help of the following code, I can check an item by CMD
var p = new Process
{
StartInfo =
{
UseShellExecute = false,
RedirectStandardOutput = true,
CreateNoWindow = true,
FileName = "cmd",
Arguments = $"list {Id}"
}};
p.Start();
var _Data = await p.StandardOutput.ReadToEndAsync();
But the question is, I want all of these items to be checked quickly by CMD, I'm currently doing this as follows
foreeach(var item in list)
{
var p = new Process
{
StartInfo =
{
UseShellExecute = false,
RedirectStandardOutput = true,
CreateNoWindow = true,
FileName = "cmd",
Arguments = $"list {item}"
}};
p.Start();
var _Data = await p.StandardOutput.ReadToEndAsync();
}
But it takes a long time to do this
You can redirect standard input and use a StreamWriter to write to it:
Process p = new Process();
ProcessStartInfo info = new ProcessStartInfo();
info.FileName = "cmd.exe";
info.RedirectStandardInput = true;
info.UseShellExecute = false;
p.StartInfo = info;
p.Start();
using (StreamWriter sw = p.StandardInput)
{
if (sw.BaseStream.CanWrite)
{
sw.WriteLine("mysql -u root -p");
sw.WriteLine("mypassword");
sw.WriteLine("use mydb;");
}
}

How do I check if a command prompt command executes valid? [duplicate]

This question already has answers here:
How To: Execute command line in C#, get STD OUT results
(18 answers)
Closed 1 year ago.
So I want to check if node.js is installed using c# by using this code.
System.Diagnostics.Process process = new System.Diagnostics.Process();
System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
startInfo.FileName = "cmd.exe";
startInfo.Arguments = "/C node -v";
process.StartInfo = startInfo;
process.Start();
I'm not sure how to check if the command ran successfully. Is it possible in c# and if it is how?
Set StartInfo appropiately and redirects the standard output.
var proc = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = "cmd.exe",
Arguments = "/C node -v",
UseShellExecute = false,
RedirectStandardOutput = true,
CreateNoWindow = true
}
};
// Starts the process and reads its output.
proc.Start();
string output = proc.StandardOutput.ReadToEnd();

Process Get the outpout of a CMD command

Im trying to get the outpout of my CMD command and i get the wrong outpout:
here's my cmd command : cm whoami
here's the outpout i should get (CMD outpout) :
C:\Users\Joevin>cm whoami
JoevinFerret
here's my code :
Process process = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = "cmd.exe",
Arguments = "cm whoami",
UseShellExecute = false,
RedirectStandardOutput = true,
CreateNoWindow = true
}
};
process.Start();
string outpout = process.StandardOutput.ReadLine();
here's the outpout that i get :
outpout = "Microsoft Windows [Version 10.0.19041.804]"
Thanks to Mathias.R and Christian.K i have been able to find a solution.
Here's my code:
Process process = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = "cmd.exe",
Arguments = "/c cm whoami",
UseShellExecute = false,
RedirectStandardOutput = true,
CreateNoWindow = true
}
};
process.Start();
string outpout = process.StandardOutput.ReadToEnd();
process.WaitForExit();

.Net Core open external terminal

I'm migrating batch script to .Net core and I'm trying to open another terminal from current terminal and run a command (I don't need stderr o stout).
With batch only needs this command: start cmd /K gulp. I'm trying to do the same with .Net core but only found the way to run the command inside current terminal.
private static string Run (){
var result = "";
try
{
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = "cmd.exe";
startInfo.Arguments = $"/c \"gulp browserSync\"";
startInfo.RedirectStandardOutput = true;
startInfo.RedirectStandardError = true;
startInfo.UseShellExecute = false;
startInfo.CreateNoWindow = true;
using (Process process = Process.Start(startInfo))
{
result = process.StandardError.ReadToEnd();
process.WaitForExit();
}
}
catch (Exception Ex)
{
Console.WriteLine(Ex.Message);
Console.ReadKey();
}
return result;
}
I'm trying changing this properties in order to open in another terminal:
startInfo.RedirectStandardOutput = false;
startInfo.RedirectStandardError = false;
startInfo.UseShellExecute = true;
But make an exception:
UseShellExecute must always be set to false.
From the MSDN docs:
UseShellExecute must be false if the UserName property is not null or an empty string, or an InvalidOperationException will be thrown when the Process.Start(ProcessStartInfo) method is called.
startInfo.UserName = null;
edit: I'm not sure why you have to pass in the arguments, but if all you want is a new CMD window try this:
try
{
ProcessStartInfo startInfo = new ProcessStartInfo
{
FileName = "cmd.exe",
WorkingDirectory = #"C:/users/replace/where_gulp_is_located",
Arguments = #"/c gulp", // add /K if its required, I don't know if its for gulp for to open a new cmd window
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true
};
Process proc = new Process();
proc.StartInfo = startInfo;
proc.Start();
if (showOut)
{ ///code }
}catch(Exception ex)
{
Console.WriteLine(ex);
}
You wont need startInfo.UserName in this case because you are specifying a working directory.
Thanks to #bender-bending answer I found a way to solve it. Due security limitations need user/password credentials in order to autorice current terminal to open a new one.
WorkingDirectory, user, password and domain are required.
Create no window, redirect output and redirect error must be false, in order to see command result in new window.
public static void Sample(){
try
{
Console.Write("Password: ");
StringBuilder password = new StringBuilder();
while (true)
{
var key = System.Console.ReadKey(true);
if (key.Key == ConsoleKey.Enter) break;
password.Append(key.KeyChar);
}
ProcessStartInfo startInfo = new ProcessStartInfo
{
FileName = "cmd.exe",
WorkingDirectory = "C:/path_to/Gulp",
Arguments = $"/c \"gulp browserSync\"",
UseShellExecute = false,
RedirectStandardOutput = false,
RedirectStandardError = false,
UserName = Machine.User(),
PasswordInClearText = password.ToString(),
Domain = Machine.Domain(),
CreateNoWindow = false
};
Process proc = new Process();
proc.StartInfo = startInfo;
proc.Start();
//proc.WaitForExit();
} catch (Exception ex)
{
System.Console.WriteLine(ex);
System.Console.ReadKey();
}
}
.Net Core doesn't have a method to obtain user and domain. We can use this class to get this values from environment variables.
public static class Machine
{
public static string User(){
return Environment.GetEnvironmentVariable("USERNAME") ?? Environment.GetEnvironmentVariable("USER");
}
public static string Domain(){
return Environment.GetEnvironmentVariable("USERDOMAIN") ?? Environment.GetEnvironmentVariable("HOSTNAME");
}
}
Hope it helps!

Categories

Resources