How do I use ProcessStartInfo to run a batch file? - c#

But it doesn't work -meaning the java code is not executed.
Although the batch file runs fine when clicked in Windows explorer or when run in command line ..
Since this works fine when the batch file is a single DOS command, I think this is somehow related to the fact that the Java code needs ~20 minutes to run.
I'm using the following code
var si = new ProcessStartInfo();
si.CreateNoWindow = true;
si.FileName = batchFileName;
si.UseShellExecute = false;
Process.Start(si);
What am I doing wrong?

Set UseShellExecute to true, so it loads cmd.exe to run the batch file.

Check this - a batch file wrapper of ProcessStartInfo:
C:\>ProcessStartJS.bat "cmd.exe" -arguments "/c pause" -style Minimized -priority High -newWindow yes -useshellexecute yes
Started: cmd.exe /c pause
PID:6540

As Lucas Jones mentioned in the comments, if you don't want to use ShellExecute, do it like this:
string fullBatPath = #"C:\path with space\file.bat";
var process = new Process()
{
StartInfo = new ProcessStartInfo
{
FileName = "cmd.exe",
Arguments = $"cmd /C \"{fullBatPath}\"",
UseShellExecute = false,
CreateNoWindow = true,
}
};
process.Start();

Related

Running multiple commands from C# application

I want to run several commands via C# application like
Previously I had a batch file and I ran it using C# but now few of the commands can take inputs. But how to do that ?
I tried
Process cmdprocess = new Process();
ProcessStartInfo startinfo = new ProcessStartInfo();
Environment.SetEnvironmentVariable("filename", FileName);
startinfo.FileName = #"C:\Users\cnandy\Desktop\St\2nd Sep\New_CN\New folder\Encrypt web.config_RSAWebFarm\Decrypt Connection String.bat";
startinfo.WindowStyle = ProcessWindowStyle.Hidden;
startinfo.CreateNoWindow = true;
startinfo.RedirectStandardInput = true;
startinfo.RedirectStandardOutput = true;
startinfo.UseShellExecute = false;
cmdprocess.StartInfo = startinfo;
cmdprocess.Start();
And in the batch file
cd C:\Windows\Microsoft.NET\Framework64\v4.0.30319
aspnet_regiis -pi "CustomKeys2" "C:\Users\cnandy\Desktop\Encryption_keys\CustomEncryptionKeys.xml"
aspnet_regiis -pa "CustomKeys2" "NT AUTHORITY\NETWORK SERVICE"
aspnet_regiis -pdf "connectionStrings" %filename%
But effectively they did not run get executed at all. How to achieve the same where for the last command I can accept an input instead of hard coding
"C:\Users\cnandy\Desktop\Test\Websites\AccountDeduplicationWeb"
?
Try this:
Process p = new Process()
{
StartInfo = new ProcessStartInfo("cmd.exe")
{
RedirectStandardInput = true,
RedirectStandardOutput = true,
UseShellExecute = false,
CreateNoWindow = true
}
};
p.Start();
using (StreamWriter sw = p.StandardInput)
{
sw.WriteLine("First command here");
sw.WriteLine("Second command here");
}
p.StandardInput.WriteLine("exit");
Alternatively, try this more direct way (which also implements the last thing you requested):
string strEntry = ""; // Let the user assign to this string, for example like "C:\Users\cnandy\Desktop\Test\Websites\AccountDeduplicationWeb"
Process p = new Process()
{
StartInfo = new ProcessStartInfo("cmd.exe")
{
RedirectStandardInput = true,
RedirectStandardOutput = true,
UseShellExecute = false,
CreateNoWindow = true
}
};
p.Start();
p.StandardInput.WriteLine("cd C:\\Windows\\Microsoft.NET\\Framework64\\v4.0.30319");
p.StandardInput.WriteLine("aspnet_regiis -pi \"CustomKeys2\" \"C:\\Users\\cnandy\\Desktop\\Encryption_keys\\CustomEncryptionKeys.xml\"");
p.StandardInput.WriteLine("aspnet_regiis -pa \"CustomKeys2\" \"NT AUTHORITY\\NETWORK SERVICE\"");
p.StandardInput.WriteLine("aspnet_regiis -pdf \"connectionStrings\" " + strEntry);
p.StandardInput.WriteLine("exit"); //or even p.Close();
If using the second way, it is recommended to let the user enter the path in a textbox, then grab the string from the textbox's Text property, where all the necessary extra back-slashes will be automatically appended.
It should be mentioned that no cmd will show up running your batch file, or the commands.
You can still make a batch file as you used to. Only change it needs is accepting variables.
Something like
CallYourBatch.bat "MyFileName"
Then in you batch file, you can accept a parameter
SET fileName=%~1
aspnet_regiis -pdf "connectionStrings" %fileName%
Similarly the same functionality can be used while forming your command text, if you must do it as part of C# code.
Also might i suggest using a CALL command to call your batch files? More information on the same is at http://ss64.com/nt/call.html
Start the batch file using Process object. You can use Environment variables to pass the values between processes. in this case, from C# to bat file you can pass values using environment variable.
c#
Environment.SetEnvironmentVariable("searchString","*.txt")
in bat file you can access the value as like below
dir %searchString%
To start the bat file from c#
System.Diagnostics.Process.Start("path\commands.bat");
Sample code to start notepad from C# with Batch file and Variables
System.Environment.SetEnvironmentVariable("fileName", "test.txt");
System.Diagnostics.Process.Start(System.IO.Path.GetDirectoryName(Assembly.GetEntryAssembly().Location) + "/commands.bat");
Console.ReadLine();
Bat file
#echo "staring note pad"
notepad %fileName%

Executing batch file located on remote machine

I'm trying to execute a batch file that is located on a remote machine with the following line of code:
System.Diagnostics.Process.Start(\\10.0.24.103\somePath\batchFile.bat);
And it blocks on this line of code. When I try to run it manually (by writing that address in Windows Explorer), it works, but I have to accept a security warning message first. I'm assuming this is why it's blocking when it's done through code...is there any way to force it to execute through code?
I solved my problem by adding more detail to the ProcessStartInfo object:
var process = new Process();
var startInfo = new ProcessStartInfo
{
CreateNoWindow = true,
FileName = "cmd.exe",
Arguments = "/c \"\"" + batchFile + "\"\"",
WorkingDirectory = AppDomain.CurrentDomain.BaseDirectory,
UseShellExecute = false,
RedirectStandardError = true,
RedirectStandardOutput = true
};
process.StartInfo = startInfo;
process.Start();
process.WaitForExit(30000);
I needed to specify to use cmd.exe, as well as surrounding the batchFile path in double quotes in case there are spaces in the path.
Try prefacing it with cmd /c(that's a space after /c).
Is this IP address a Windows machine on your domain etc.

Command Line Process

So after scouring the web I found a few articles (some on stackoverflow) which described how to execute a command line prompt by starting a new process in c#. The second argument, which I've commented out, works just fine, but the one I actually need (the first one) doesn't. It returns the error "Could not find or load main class edu.stanford.nlp.parser.lexparser.LexicalizedParser" When I open up a command line (non-programatically) and then execute the same command (aside from the escaped quotations) it works great. Any idea's about what the problem could be? Thanks!
var proc = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = "CMD.exe",
Arguments = "/c java -mx100m -cp \"*\" edu.stanford.nlp.parser.lexparser.LexicalizedParser edu/stanford/nlp/models/lexparser/englishPCFG.ser.gz libtest.txt",
// Arguments = "/c echo Foo",
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
CreateNoWindow = true
}
};
proc.Start();
Console.WriteLine(proc.StandardOutput.ReadToEnd());
Console.WriteLine(proc.StandardError.ReadToEnd());
Ensure that the executing path where you start your process is correct!
You can use Process Monitor from SysInternals to figure out where that class is looked for.

Stop new command window opening each time command is executed

I have written a C# tool that will launch an application by running a command in the command prompt for me several times, one after the other. The piece of code doing this for me is as follows:
System.Diagnostics.Process.Start("CMD.exe", strCmdText);
So I have this in a loop and all is good. However each time it executes a new command window is opened, which isnt ideal. Is there a way I can close the command window after the command has executed, or better still, not have the command window open at all? Any help is really appreciated!!
Yes, you have to use the ProcessStartInfo class for doing this:
Process.Start(
new ProcessStartInfo("CMD.exe", strCmdText)
{
CreateNoWindow = true
});
Use ProcessStartInfo to start the process (Start has an overload that takes a ProcessStartInfo).
Set the following properties:
var psi = new ProcessStartInfo("cmd.exe", strCmdText);
psi.CreateNoWindow = true;
psi.UseShellExecute = false;
Process.Start(psi);
ProcessStartInfo allows you to specify no window.
using (var p = new Process())
{
p.StartInfo = new ProcessStartInfo
{
FileName = "CMD.exe",
Arguments = strCmdText,
CreateNoWindow = true,
UseShellExecute = false
};
p.Start();
p.WaitForExit();
p.Close();
}

Start command windows and run commands inside

I need to start the command window with some arguments and run more commands inside.
For example, launch a test.cmd and run mkdir.
I can launch the test.cmd with processstartinfo , but i am not sure how to run further commands. Can I pass further arguments to the test.cmd process?
How do I go about this?
Unable to add comments to answer... SO writing here.
Andrea, This is what I was looking for. However the above code doesnt work for me.
I am launching a test.cmd which is new command environment (like razzle build environment) and I need to run further commands.
psi.FileName = #"c:\test.cmd";
psi.Arguments = #"arg0 arg1 arg2";
psi.RedirectStandardInput = true;
psi.RedirectStandardOutput = true;
psi.CreateNoWindow = true;
psi.UseShellExecute = false;
Process p = new Process();
p.StartInfo = psi;
p.Start();
p.StandardInput.WriteLine(#"dir>c:\results.txt");
p.StandardInput.WriteLine(#"dir>c:\results2.txt");
You can send further commands to cmd.exe using the process
standard input. You have to redirect it, in this way:
var startInfo = new ProcessStartInfo
{
FileName = "cmd.exe",
RedirectStandardInput = true,
RedirectStandardOutput = true,
UseShellExecute = false,
CreateNoWindow = true
};
var process = new Process {StartInfo = startInfo};
process.Start();
process.StandardInput.WriteLine(#"dir>c:\results.txt");
process.StandardInput.WriteLine(#"dir>c:\results2.txt");
process.StandardInput.WriteLine("exit");
process.WaitForExit();
Remember to write "exit" as your last command, otherwise the cmd process doesn't terminate correctly...
The /c parameter to cmd.
ProcessStartInfo start = new ProcessStartInfo("cmd.exe", "/c pause");
Process.Start(start);
(pause is just an example of what you can run)
But for creating a directory you can do that and most other file operations from c# directly
System.IO.Directory.CreateDirectory(#"c:\foo\bar");
Start a cmd from c# is useful only if you have some big bat-file that you don't want to replicate in c#.
What are you trying to achieve? Do you actually need to open a command window, or do you need to simply make a directory, for example?
mkdir is a windows executable - you can start this program in the same way you start cmd - there's no need to start a command window process first.
You could also create a batch file containing all the commands you want to run, then simply start it using the Process and ProcessStartInfo classes you're already using.
How come this doesn't work?
var startInfo = new ProcessStartInfo
{
FileName = "cmd.exe",
RedirectStandardInput = true,
RedirectStandardOutput = true,
UseShellExecute = false,
CreateNoWindow = false
};
var process = new Process { StartInfo = startInfo };
process.Start();
process.StandardInput.WriteLine(#" dir");
process.WaitForExit();

Categories

Resources