Issue running batch file in a WinForms app - c#

As part of my program I need to run a batch file.
The person I'm doing it for doesn't want anyone to be able to view the batch script, so I tried to include it in a WinForms solution, but I can't get it to run, I just get a time out error.

Michael,
You can do it two different way.
To provide script file in Process, but it will expose your code, as its open in file.
You can start command prompt by your process and supply your code as an argument.
var p = new Process();
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.Arguments = "/c mycmd.exe 2>&1";
OR
var p = new Process();
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.Arguments = #"/c dir \windows";
p.StartInfo.CreateNoWindow = true;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardInput = false;
p.OutputDataReceived += (a, b) => Console.WriteLine(b.Data);
p.ErrorDataReceived += (a, b) => Console.WriteLine(b.Data);
p.Start();
p.BeginErrorReadLine();
p.BeginOutputReadLine();
p.WaitForExit();

Related

Start process and get its output constantly

I have a console program written in c++, and I would like to continually check its output to use in my c# project.
This is the code I've tried to steal from another StackOverflow question, but with no luck.
Edit:( By no luck, I mean: the output is pretty much empty, although if I set p.StartInfo.CreateNoWindow to false, I can see my script.exe launch and output into its window. )
Process p = new Process();
p.StartInfo.FileName = #"external\script.exe";
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.CreateNoWindow = true;
p.Start();
string output = p.StandardOutput.ReadToEnd();
p.WaitForExit();
Console.WriteLine("Output:");
Console.WriteLine(output);
I had a similar issue and it had to do with where the output was going. The solution was to run cmd and execute my script from the cmd process. See this answer to another question for more information. reading from stdout and stderr together Your new code would look like:
Process p = new Process();
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.Arguments = "/c yourscriptpath.exe 2>&1";
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.CreateNoWindow = true;
p.Start();
string output = p.StandardOutput.ReadToEnd();
p.WaitForExit();
Console.WriteLine("Output:");
Console.WriteLine(output);

output limitation when calling exe file from c# code

I have an exe file that I call it from my c# code by using Process namespace in c#.
I catch output by using ReadToEnd() method. (in exe source code i used a print method for my desired output).
the problem is when my output is getting larger the executing of exe file is got crashed and hanged.
Is there any limitation of output size when calling exe function?
Process p = new Process();
p.StartInfo.FileName = command;
p.StartInfo.UseShellExecute = false;
p.StartInfo.CreateNoWindow = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.Arguments = args;
p.Start();
p.WaitForExit();
string output = p.StandardOutput.ReadToEnd();
return output;
What you're experiencing is a deadlock. That situation is described in the documentation. In order to avoid it, make sure you read the output before waiting for the child process to exit.
p.Start();
string output = p.StandardOutput.ReadToEnd();
p.WaitForExit();
I remember having the same problem as you're describing here, and what I did back then was something like this:
private string RunProcess(string command, string args)
{
StringBuilder sb = new StringBuilder();
Process p = new Process();
p.StartInfo.FileName = command;
p.StartInfo.UseShellExecute = false;
p.StartInfo.CreateNoWindow = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.Arguments = args;
p.OutputDataReceived += (sender, eventArgs) => { sb.Append(eventArgs.Data); };
p.Start();
p.WaitForExit();
return sb.ToString();
}

Keep console window of a new Process open after it finishes

I currently have a portion of code that creates a new Process and executes it from the shell.
Process p = new Process();
...
p.Start();
p.WaitForExit();
This keeps the window open while the process is running, which is great. However, I also want to keep the window open after it finishes to view potential messages. Is there a way to do this?
It is easier to just capture the output from both the StandardOutput and the StandardError, store each output in a StringBuilder and use that result when the process is finished.
var sb = new StringBuilder();
Process p = new Process();
// redirect the output
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardError = true;
// hookup the eventhandlers to capture the data that is received
p.OutputDataReceived += (sender, args) => sb.AppendLine(args.Data);
p.ErrorDataReceived += (sender, args) => sb.AppendLine(args.Data);
// direct start
p.StartInfo.UseShellExecute=false;
p.Start();
// start our event pumps
p.BeginOutputReadLine();
p.BeginErrorReadLine();
// until we are done
p.WaitForExit();
// do whatever you need with the content of sb.ToString();
You can add extra formatting in the sb.AppendLine statement to distinguish between standard and error output, like so: sb.AppendLine("ERR: {0}", args.Data);
This will open the shell, start your executable and keep the shell window open when the process ends
Process p = new Process();
ProcessStartInfo psi = new ProcessStartInfo();
psi.FileName = "CMD.EXE";
psi.Arguments = "/K yourmainprocess.exe";
p.StartInfo = psi;
p.Start();
p.WaitForExit();
or simply
ProcessStartInfo psi = new ProcessStartInfo();
psi.FileName = "CMD.EXE";
psi.Arguments = "/K yourmainprocess.exe";
Process p = Process.Start(psi);
if(p != null && !p.HasExited)
p.WaitForExit();
Be carefull espacially on switch /k, because in many examples is usually used /c.
CMD /K Run Command and then return to the CMD prompt.
CMD /C Run Command and then terminate
var p = new Process();
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.Arguments = "/k yourmainprocess.exe";
p.Start();
p.WaitForExit();
Regarding: "Member Process.Start(ProcessStartInfo) cannot be accessed with an instance reference; qualify it with a type name instead"
This fixed the problem for me....
ProcessStartInfo psi = new ProcessStartInfo();
psi.FileName = "CMD.EXE";
psi.Arguments = "/K yourmainprocess.exe";
Process p = Process.Start(psi);
p.WaitForExit();

create process and attach C#

I have a doubt, when I create a new process iexplore, and this process opens one single page, I would like know if the page loads correctly. How can I learn if the page load fails ?. Is there any way to catch an error from iexplore process?
I have this demo code, but doesn't work correctly
string navegador = "C:\\program files (x86)\\Internet Explorer\\iexplore.exe";
Process p = new Process();
p.StartInfo.FileName = navegador;
ProcessStartInfo processStartInfo = new ProcessStartInfo(navegador);
p.EnableRaisingEvents = false;
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.CreateNoWindow = true;
p.StartInfo = processStartInfo;
p.StartInfo.Arguments = "google.com";
p.Start();
Process currentProcess = Process.GetCurrentProcess();
Process[] localByName = Process.GetProcessesByName("iexplore");
Process[] localAll = Process.GetProcesses();
p.OutputDataReceived += new DataReceivedEventHandler(
prsProjectTypes_OutputDataReceived);
p.BeginOutputReadLine();
errorMessage = p.StandardError.ReadToEnd();
p.WaitForExit();
Thank you for any help.
Assuming you are working WPF, you should look at the Web Browser control rather than launching a separate process. This will give you access to the LoadCompleted event which seems to be what you're looking for.

Using shell commands in C#

I've the below code where I use DevCon.exe to capture something and write it in a file. I parse this file for a need.
Process p = new Process();
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.Arguments = "/C devcon.exe find = port *monitor* > monitor_Details.txt";
p.StartInfo.CreateNoWindow = true;
p.StartInfo.UseShellExecute = true;
p.StartInfo.Verb = "runas";
p.Start();
Unfortunately, with this code, I dont see any textfile created. So, here shell commands are not considered though I mentioned.
Same command is working in CMDLine.
Can anyone pls help as to what's going wrong?
I tried with below code as well and it does not work.
Process p = new Process();
p.StartInfo.FileName = "devcon.exe";
p.StartInfo.Arguments = "find = port *monitor* > monitor_Details.txt";
p.StartInfo.CreateNoWindow = true;
p.StartInfo.UseShellExecute = true;
p.StartInfo.Verb = "runas";
p.Start();
You can add theses lines - based on RedirectStandardOutput
p.StartInfo.RedirectStandardOutput = true;
.....
p.Start();
string result = p.StandardOutput.ReadToEnd();
Link : http://msdn.microsoft.com/fr-fr/library/system.diagnostics.processstartinfo.redirectstandardoutput.aspx
I had the exact same problem. A workaround is to provide the UserName and Password parameters for the process as well as the "runas" verb. This will make the new process start elevated and be able to Read/Write files. I don't have clear explanation but it worked for me.
p.StartInfo.Verb = "runas";
p.StartInfo.UserName = Environment.UserName;
p.StartInfo.Password = PromptUserPassword(); //Get password as SecureString

Categories