Process.Exited event is not be called - c#

I have the following code snippet to call into command line:
p = new Process();
ProcessStartInfo psi = new ProcessStartInfo();
psi.FileName = "cmd.exe";
psi.Arguments = "/C " + "type " + “[abc].pdf”;
psi.UseShellExecute = false;
psi.RedirectStandardInput = false;
psi.RedirectStandardOutput = true;
psi.CreateNoWindow = true;
p.StartInfo = psi;
p.EnableRaisingEvents = true;
p.Exited += new EventHandler(p_Exited);
p.Start();
p.WaitForExit();
Strangely, When [abc] is a small pdf file(8kb) p_Exited is called. But when it's a large pdf file(120kb) it is never called. Any clues?
Thanks,

You need to consume the output stream when the standard output has been redirected:
p.Start();
p.StandardOutput.ReadToEnd();
p.WaitForExit();

Related

Printing PDF file with Custom Page size

How can I print PDF file without changing the page size? I use the code below but it changes the paper size.
ProcessStartInfo info = new ProcessStartInfo();
info.Verb = "print";
info.FileName = FilePath;
info.CreateNoWindow = true;
info.WindowStyle = ProcessWindowStyle.Hidden;
Process p = new Process();
p.StartInfo = info;
p.Start();
p.WaitForInputIdle();
System.Threading.Thread.Sleep(3000);
if (false == p.CloseMainWindow())
p.Kill();

C# with WMIC command

I'm trying to execute wmic command on C# and get the output, but the function is only returning first line and the command which is not running.
Code:
private static String wimc(String cmd)
{
var psi = new ProcessStartInfo("wmic");
psi.Arguments = #"shadowcopy call create Volume='C:\'";
psi.WindowStyle = ProcessWindowStyle.Hidden;
psi.UseShellExecute = false;
psi.RedirectStandardOutput = true;
var p = Process.Start(psi);
p.WaitForExit();
String output = p.StandardOutput.ReadToEnd();
return output;
}
Output on C#:
Executing (Win32_ShadowCopy)->create()
Only show first line and command not working
Cmd output(expected)
Executing (Win32_ShadowCopy)->create() Method execution successful. Out Parameters: instance of __PARAMETERS {
ReturnValue = 0;
ShadowID = "{B2FDCFDE-7C48-4F96-9648-9A15DB89506C}";
};
shadowcopy on cmd was created with sucess
For redirecting wmic to the console output you need to add /OUTPUT:STDOUT to your arguments.
And of course you will need to run your C# application as administrator.
var psi = new ProcessStartInfo("wmic");
psi.Arguments = #"/OUTPUT:STDOUT shadowcopy call create Volume='C:\'";
psi.WindowStyle = ProcessWindowStyle.Hidden;
psi.UseShellExecute = false;
psi.RedirectStandardOutput = true;
psi.RedirectStandardError = true;
var p = Process.Start(psi);
p.WaitForExit();
String output = p.StandardOutput.ReadToEnd();
String errOutput = p.StandardError.ReadToEnd();
Here is what worked for me.
System.Diagnostics.ProcessStartInfo usbDevicesInfo = new System.Diagnostics.ProcessStartInfo("wmic", "path CIM_USBDevice get Caption");
usbDevicesInfo.RedirectStandardOutput = true;
usbDevicesInfo.UseShellExecute = false;
usbDevicesInfo.CreateNoWindow = true;
System.Diagnostics.Process process = new System.Diagnostics.Process();
process.StartInfo = usbDevicesInfo;
process.Start();
process.WaitForExit();
Console.WriteLine("ExitCode: " + process.ExitCode.ToString() + "\n");
result = process.StandardOutput.ReadToEnd();
Console.WriteLine(result);

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();

Executing batch file from c# silently

I know this question has been asked previously and I have tried all the solutions given in those posts before but I can't seem to make it work:-
static void CallBatch(string path)
{
int ExitCode;
Process myProcess;
ProcessStartInfo ProcessInfo;
ProcessInfo = new ProcessStartInfo("cmd.exe", "/c " + path);
ProcessInfo.CreateNoWindow = true;
ProcessInfo.UseShellExecute = true;
myProcess = Process.Start(ProcessInfo);
myProcess.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
myProcess.WaitForExit();
myProcess.EnableRaisingEvents = true;
myProcess.Exited += new EventHandler(process_Exited);
ExitCode = myProcess.ExitCode;
Console.WriteLine("ExitCode: " + ExitCode.ToString(), "ExecuteCommand");
myProcess.Close();
}
When I try to call the batch file, it still shows the window even though createNoWindow and UseShellExecute are both set to true.
Should I put something else to make it run the batch file silently?
Try this:
Process myProcess = new Process();
myProcess.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
myProcess.StartInfo.CreateNoWindow = true;
myProcess.StartInfo.UseShellExecute = false;
myProcess.StartInfo.FileName = "cmd.exe";
myProcess.StartInfo.Arguments = "/c " + path;
myProcess.EnableRaisingEvents = true;
myProcess.Exited += new EventHandler(process_Exited);
myProcess.Start();
myProcess.WaitForExit();
ExitCode = myProcess.ExitCode;
The idea is to not manipulate myProcess.StartInfo after you have started your process: it is useless. Also you do not need to set UseShellExecute to true, because you are starting the shell yourself by calling cmd.exe.

C# Multiple Input and Output to a Single CMD Process

Hi how do i enter a command to a cmd process which is already started by my application and also to redirect the output back. After that i want to enter my input again.
static void Main(string[] args)
{
ProcessStartInfo psi = new ProcessStartInfo();
psi.CreateNoWindow = false;
psi.FileName = "cmd.exe";
psi.Arguments = "/k";
psi.UseShellExecute = false;
psi.RedirectStandardOutput = true;
psi.RedirectStandardInput = true;
Process p = new Process();
p.StartInfo = psi;
p.Start();
while(true)
{
p.StandardInput.WriteLine(Console.ReadLine());
Console.WriteLine(p.StandardOutput.ReadToEnd());
}
Console.Read();
}

Categories