I am having a Java batch process which I used in C# to run process. I want to have a testcase to check whether the batch process is running or not.
I used the batch process as:
void batch_process(string process)
{
try
{
string strFilePath = Path.Combine(batch_process_path, process);
ProcessStartInfo psi = new ProcessStartInfo(strFilePath);
psi.RedirectStandardOutput = true;
psi.RedirectStandardError = true;
psi.WorkingDirectory = batch_process_path;
psi.WindowStyle = ProcessWindowStyle.Hidden;
psi.UseShellExecute = false;
psi.ErrorDialog = true;
}
}
How can this test be done?
I want to write an unit test case to check whether the process will start or not.
when you Start your new process you need to capture the returned Process, that provides access to newly started process, useful for starting, stopping, controlling, and monitoring applications.
Process exe = Process.Start(psi);
....
if exe.HasExited() ....
You could start the process using
Process process = new Process();
string strFilePath = Path.Combine(batch_process_path, process);
process.StartInfo.FileName = strFilePath;
//this line will hold this thread until the process is done.
process.WaitForExit();
then start the process on a different thread and let that thread fire an event after process.WaitForExit(); is done.
You should first start the process using the ProcessStartInfo you've just created like:
Process process = Process.Start(psi);
then you can use process.HasExited to check if the process has exited. Often, you don't need to do this, as process.WaitForExit() blocks the code until process exits.
I'm a bit unsure of the scenario from your question... but 4 techniques you can use are:
if you have started the process using var process = Process.Start(psi); then:
you can periodically check process.HasExited - http://msdn.microsoft.com/en-us/library/system.diagnostics.process.hasexited.aspx
or you can subscribe to Process.Exited - http://msdn.microsoft.com/en-us/library/system.diagnostics.process.exited.aspx
or you can block on Process.WaitForExit - http://msdn.microsoft.com/en-us/library/system.diagnostics.process.waitforexit.aspx
if your process is started in some other way and has some unique name, then you can inspect the enumeration returned by System.Diagnostics.Process.GetProcesses() to determine if your batch process is currently running.
In general... I'd prefer to use Process.Exited, but the other methods all have their place too!
Related
using this Code
Process process = new Process();
// p.EnableRaisingEvents = true;
process.EnableRaisingEvents = true;
process.OutputDataReceived += new DataReceivedEventHandler(p_OutputDataReceived);
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.CreateNoWindow = true;
process.StartInfo.LoadUserProfile = false;
process.StartInfo.UseShellExecute = false;
process.StartInfo.FileName = #"C:\putty.exe"; ; // Gets or sets the application or document to start.
process.StartInfo.Arguments = "-serial com31 -sercfg 9600,8,n,1,N";//Gets or sets the set of command-line arguments to use when starting the application
Thread.Sleep(1000);
process.Start();//Starts (or reuses) the process resource that is specified by the StartInfo property of this Process component and associates it with the component.
process.BeginOutputReadLine();
process.WaitForExit(); // wait forever with ping
I'm trying to open putty in console application , but any timr I use it it opens in New windows and I cant get to output of the process using process.OutputDataReceived event
I'm using code very similar to this to open Iperf and it works fine
What am I missing here ?
Putty is not a console application and therefore does not provide output on it's stdout and stderr streams.
And since it is a windowed application it does not care whether you start it with the CreateNoWindow flag. Try and start notepad.exe with that flag, you will see it appearing obviously.
There is however a programm by the creators of Putty that provides the functionality you need.
It's called Plink.exe and you can download it on their homepage
Im trying to be close the calculator when the user press's a key on the key board. But p.kill and p.CloseMainWindow doesn't kill the calculator, only the shell which is executed.
Process p = new Process();
p.StartInfo.FileName = "cmd";
p.StartInfo.Arguments = "/c calc ";
p.StartInfo.CreateNoWindow = true;
p.StartInfo.UseShellExecute = false;
p.Start();
Console.WriteLine("Press any key to kill Calc");
Console.ReadKey();
p.CloseMainWindow();
p.Kill();
Don't use the shell (cmd) but run the calc process directly. Setting Process.StartInfo.FileName to "calc" should do it (assuming calc.exe is on the system path).
You need to find the Calculator process and kill it. There are actually two processes created: one for the cmd and the other for Calculator. You are killing only the first one.
The other solution is to start the Calculator directly, without using cmd.
because your process is not the calc.exe process but the command prompt which executes the calc.
to find a process by name and kill it, you should use GetProcessByName,
see an example here: C# Process Process.GetProcessesByName, Kill Process and Exit Event
I'm trying to run a command via command prompt from an ASP.Net web application. I can see the process start in task manager on the web server, however the process just sits there and never exits nor does it run the commands I specified.
Process process = new Process();
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = "cmd.exe";
startInfo.Arguments = "/C " +command;
startInfo.UserName = "myuser";
startInfo.UseShellExecute = false;
startInfo.RedirectStandardOutput = true;
startInfo.Domain = "mydomain";
startInfo.CreateNoWindow = true;
String pass = "mypass";
System.Security.SecureString secPass = new System.Security.SecureString();
foreach (char c in pass.ToCharArray())
{
secPass.AppendChar(c);
}
secPass.MakeReadOnly();
startInfo.Password = secPass;
process.StartInfo = startInfo;
process.Start();
//output = process.StandardOutput.ReadToEnd();
process.WaitForExit();
process.Close();
I've tried both with and without reading the standard output.
The application will hang on process.WaitForExit(); until I kill the process via task manager.
I think we need to understand what commands you are actually trying to process in order to determine what's going on. Also we need to know what OS the server is running.
For example, I did see in your comments where you tried "echo test > C:\test.txt" Under Windows Server 2008 (and Windows 7) the root directory requires administrator permissions in order to create files. If this is executing under IIS, my guess is that your IIS user isn't an administrator and you are getting security exceptions.
Also, a number of commands may require elevated priviledges due to UAC. I don't remember exactly, but I'm guessing that if those commands are being caught by UAC then the process is waiting for UAC confirmation... Which I believe you cannot supply via a command line.
This type of problem won't be seen if you log into the machine and execute it directly... unless you are logging in with the worker process user account.
So, the very first thing you need to do is figure out what it is you are trying to run and see if the user the worker process is executing under can even perform those actions. Security is there to protect you, so be careful about granting additional permissions to the user.
The reason why it might work on one machine versus another again depends on the OS's those machines are running and the configuration of the user the commands are executing under.
If this is truly a security issue, as I suspect, then you should post a question on serverfault.com to ask what permission sets you need to execute various commands under your worker process user.
You might look at the machines event logs to see if there were any warnings or errors thrown about the command. Sometimes things like this can show up there to give you a bit more information as to what happened.
Once passed to CMD, the control has passed to the shell. It's better to add a close it like this:
private void closeSubProcess()
{
Process[] currentProcesses = Process.GetProcesses();
foreach (Process p in currentProcesses)
{
string s = p.ProcessName;
s = s.ToLower();
if (s.CompareTo("YOURPROGRAMNAMEHERE") == 0)
{
p.CloseMainWindow();
p.Close();
}
}
}
I am calling cmd.exe to start a node module in Windows. npm obviously must be installed first, along with the node module I need, and then I can call the module with args in C#. Problem was, the cmd.exe would not shut off, I'd have to use Task Mgr (just like this question!).
//This requires npm, and the module installed by npm...
ProcessStartInfo psi = new ProcessStartInfo();
psi.FileName = "cmd.exe";
psi.WindowStyle = ProcessWindowStyle.Hidden;
psi.UseShellExecute = true; //closes command window
psi.Arguments = "/c <nodemodulename>" + file1 + ".txt " + file2 + ".log";
Process p = Process.Start(psi);
p.Close();
The /c argument was key to closing down cmd.exe. When I started out, I had put in the /K argument, which keeps the darned thing running. Solved. Hope this helps. (This is like ancient, but we always forget)
I want to use shell executable in order to respect user preferences of application to be started, but I also need to know when that particular application is closed.
Process editProcess = new Process();
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = filename;
startInfo.Verb = "edit";
startInfo.UseShellExecute = true;
editProcess.StartInfo = startInfo;
// start the default editor
editProcess.Start();
editProcess.WaitForExit();
WaitForExit seems to return when the shell process exits and not when the real process exits.
Is there a better way of knowing when started application is exited than manually parsing registry, finding correct application to start and explicitly start that app without shell execute?
Handle the process exited event:
editProcess.Exited += process_Exited;
I am using the Process class to run an exe.
The exe is a 3rd party console application that I do not control.
I wish to know whether the process is waiting for input on the command line.
Should it make any difference, I intend to kill the application should it be waiting for input.
There are suitable events for when there is output from the program waiting to be read, but I cannot see anything similar for when the process is waiting patiently for input.
ProcessStartInfo info = new ProcessStartInfo();
info.FileName = "myapp.exe";
info.CreateNoWindow = true;
info.UseShellExecute = false;
info.RedirectStandardError = true;
info.RedirectStandardInput = true;
info.RedirectStandardOutput = true;
process.StartInfo = info;
process.OutputDataReceived += new DataReceivedEventHandler(process_OutputDataReceived);
process.ErrorDataReceived += new DataReceivedEventHandler(process_ErrorDataReceived);
process.Start();
process.BeginOutputReadLine();
process.BeginErrorReadLine();
process.WaitForExit();
How do I detect that my process is waiting for input?
Depending on what the 3rd party process is doing exactly you could try polling its threads' states:
foreach(ProcessThread thread in process.Threads)
if (thread.ThreadState == ThreadState.Wait
&& thread.WaitReason == ThreadWaitReason.UserRequest)
process.Kill();
Failing that... you can try to
process.StandardInput.Close();
after calling Start(), I conjecture that an exception will be raised in the child process if it's trying to read from standard input.
If the console application has some sort of prompt waiting for input, you could periodically parse out the console output text using the Process.StandardOutput property of the process and wait for said prompt. Once the proper string is detected, you know that it's waiting for input. See http://msdn.microsoft.com/en-us/library/system.diagnostics.process.standardoutput.aspx.
Use process.StandardInput.writrLine("input");
for sending input to consol in c#