In Nunit as part of test I have to start an application let it run for i.e 1 min than stop it and next it reads results from file and asserts if values are correct. I can start and stop the application using Process.Start("app.exe"); however I am not sure how to keep it running for x seconds inside the [Test]. Any idea how to go about it? Thanks
[Test]
void TestFiles()
{
using(var process = Process.Start("app.exe"))
{
Thread.Sleep(1000);
process.Kill();
process.WaitForExit();
}
// Check your files now
}
Related
I have a C# winform application in which an optimization model is solved by OR-Tools. The optimization solver has the capability of sending the whole optimization process as stdout.This is done by:
Slvr.EnableOutput();
Solver.ResultStatus restatus = Slvr.Solve();
However, the solver does not automatically open up the console.
Currently, what I have done is:
Projects properties --> Application --> Output type --> Console Application
and the console is ready from the beginning till the end of the application run. Hence, that process stdout is automatically displayed.
What I want is to open the console exactly when the above part of code is run and display the stdout from the solver. Then wait for a key from the user to close the console and continue with the main application.
I guess your problem is you are trying to run the solver as part of the Winforms application, inside the GUI process right? But Console output is usually disabled in a Winforms application. You have basically two options:
use one of the options described here in this older SO answer to attach a console window for output to a Winforms application
split the application into two exe files: one command line program which runs the solver, and a Winforms part, just containing the UI. Then run the command line part as a separate process by System.Diagnostics.Process.Start, which allows finegrained control about output redirection. You may need the UI to pass parameters to the command line program, for example, by using a temporary file.
The second option is more work, especially for the communication between the GUI and the command line tool, but can be implemented easier in a way the GUI is not blocked, is more robust against bugs / program crashes in the solver part and performs usually better in case you want to introduce parallelization / run multiple solver processes at once.
Doc Brown has already answered your question, I'm only adding this to provide some code of how we implemented it here-- it's exactly what he suggests. We have a separate testPlugin.exe that get's started here. The communication is via files read and written on the file system. The console output gets captured in the "output handlers"
using System;
using System.Diagnostics;
using System.IO;
...
private void startTest()
{
int result = 2;
setFormStatus("working..."); // My method to inform the user with the form to wait.
getFormData(); // My method to get the data from the form
string errorMessage = null;
System.Diagnostics.Process testPlugInProcess = new System.Diagnostics.Process();
try
{
using (testPlugInProcess)
{
testPlugInProcess.StartInfo.UseShellExecute = false;
testPlugInProcess.StartInfo.FileName = System.IO.Path.Combine(assemblyDirectory, TestPlugInExe); // The name of the exe file
testPlugInProcess.StartInfo.CreateNoWindow = false;
testPlugInProcess.StartInfo.Arguments = getModelTestCommandLineArgs(); // My method to create the command line arguments
testPlugInProcess.StartInfo.RedirectStandardError = true;
testPlugInProcess.StartInfo.RedirectStandardOutput = true;
testPlugInProcess.OutputDataReceived += pluginTestOutputHandler;
testPlugInProcess.ErrorDataReceived += pluginTestOutputHandler;
testPlugInProcess.Start();
testPlugInProcess.BeginErrorReadLine();
testPlugInProcess.BeginOutputReadLine();
testPlugInProcess.WaitForExit();
result = testPlugInProcess.ExitCode;
}
setFormStatus("");
}
catch (Exception ex)
{
errorMessage = ex.Message;
}
testPlugInProcess = null;
}
Both the console and error output get written to the same file here, but you could separate them.
The plug-in handler looks like this:
private static void pluginTestOutputHandler(object sendingProcess,
DataReceivedEventArgs outLine)
{
if (!String.IsNullOrEmpty(outLine.Data))
{
for (int i = 0; i < numberOfTriesForWriting; i++)
{
try
{
using (StreamWriter sw = File.AppendText(lastPlugInTestTraceFilePath)) // The file name where the data is written.
{
sw.WriteLine(outLine.Data);
sw.Flush();
return;
}
}
catch (IOException)
{
System.Threading.Thread.Sleep(msToWaitBetweenTries);
}
}
}
}
i want to truncate table using console application with parameter hour.
for example, i want to run query truncate at 12.00 AM using time in system.
this is my code in console application using c#.
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string getHour = DateTime.Now.ToString("h:mm:ss tt");
if (getHour == "12:00:00 AM")
{
Console.WriteLine("Do action to run query truncate");
//in this line i will execute query truncate.
}
// Keep the console window open in debug mode.
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
}
And this is not working. please give me solution or sample code to fix my problem.
thanks...
I would suggest few things on your code:
Don't use string comparison, but uses DateTime directly (take a look on TimeOfDay.TotalSeconds). This way, it makes the comparison a lot easier
Use repeated calls instead of just one call (unless you can really be sure that you run your program exactly at 12). This way you make your program work for you more.
To make it more robust, provide some ways to give tolerance to your system. This is how good automation should be.
Example:
namespace ConsoleApplication1 {
class Program {
static void Main(string[] args) {
while (true) { //read 2. assuming this is to be run forever in this example, but gives also some way to break the loop whenever necessary in your app
if (DateTime.Now.TimeOfDay.TotalSeconds <= 1) { //read 1. and 3. this way, you give tolerance of 1 second. Your action will be run on 12:00:00 - 12:00:01
Console.WriteLine("Do action to run query truncate");
// //in this line i will execute query truncate.
break; //break after saving once, for instance, and run again when the time close... This is to prevent possible multiple executions...
}
System.Threading.Thread.Sleep(500); //read 2. and 3. check every 500 millisecond, at least to give chance to check the time twice per second
}
// Keep the console window open in debug mode.
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
}
When you run your program, it looks on the clock quickly, and if it is not exactly midnight immediately exits. (To be more precise it prints some message and waits until keypress). I believe you wish to wait until midnight. If the exact timing is not that important (I mean some seconds early or late is acceptable), the simplest solution is:
static void Main(string[] args)
{
Thread.Sleep(DateTime.Today.AddDays(1) - DateTime.Now);
Console.WriteLine("It's about midnight, I go to sleep");
}
I feel like the issue is with the flow of execution of your code.
You're calling the code once and then it stops. It checks once NOW and get the current time. If the time is 12:00:00 AM, you can pass into the if statement, but you'll need to literally run this at 12:00:00 System time on the dot, which is nearly impossible.
You should consider a Windows Service or using Windows Task Manager: C# Console Application - Keep it running.
As mentioned in the other answers you shouldn't be using your app to schedule the task. It looks like you are doing a database maintenance task so the first thing I would look at is...
1) See if your database can schedule tasks. SQL Server Agent for example can schedule stored procedures (or adhoc SQL) to be run at set times and would accomplish your task if you are using that for your database. More info here.
If your database can't do this or you want to do other things other than truncate the table then...
2) try using Windows Task Scheduler
This can launch an application at set times, is easy to setup and then your application can just do the job it's mean to do (e.g. truncate the table) and not worry about the scheduling.
This question already has answers here:
How to start a c# program from another c# program in the same map?
(3 answers)
Closed 8 years ago.
I have 3 C# programs that need to be executed in an order(TestCSharp1, TestCSharp2 and TestCSharp3).2nd program should be executed only after first completes and 3 should execute only after 1 and 2 finish. How can I do this. Right now, I have them as scheduled tasks and I manually check if they have finished and then start others.
Use the Proccess Class (Documentation) to start a process from inside your program. Here is an example from the documentation:
using System;
using System.Diagnostics;
using System.ComponentModel;
namespace MyProcessSample
{
class MyProcess
{
public static void Main()
{
Process myProcess = new Process();
try
{
myProcess.StartInfo.UseShellExecute = false;
// You can start any process, HelloWorld is a do-nothing example.
myProcess.StartInfo.FileName = "C:\\HelloWorld.exe";
myProcess.StartInfo.CreateNoWindow = true;
myProcess.Start();
myProcess.WaitForExit(); //use this if you want to pause execution of your program till the process you have started closes.
// This code assumes the process you are starting will terminate itself.
// Given that is is started without a window so you cannot terminate it
// on the desktop, it must terminate itself or you can do it programmatically
// from this application using the Kill method.
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
}
}
Assuming you are running command line programs you can create a batch file with the three executables in it and run the batch file as a scheduled task. As you'll see in the comments, if there are Windows programs this approach will not work.
E.g.
#echo off
cd \ToTheRightPlace
TestCSharp1
TestCSharp2
TestCSharp3
You'll want to check return values, etc.
I'm trying to make a console app in c# that will confirm that another application is always running. The other application periodically crashes, and I need to check every few minutes and relaunch it if it has stopped working.
There are many questions on SO that address making sure than no more than one instance of the application is running. I'm trying to confirm that one (no more or less) is running at all times.
Does anybody know how to even begin approaching this?
I would suggest using System.Diagnostics.Process.GetProcessesByName to see if your process is running and then, if not, using System.Diagnostics.Process.Start to start the process.
var processes = Process.GetProcessesByName("yourProcessName");
if(processes.Length == 0)
{
Process.Start(#"C:\Path\To\Your\Process.exe");
}
// Kill the extras
for(int i = 1; i < process.Length; i++)
{
processes[i].Kill();
}
These commands are useful to control processes:
// check for processes
Process[] processes = Process.GetProcessesByName("nameOfExecutable");
foreach (Process proc in processes)
{
// do stuff
}
// start process (need path)
Process.Start("pathToExecutable");
// close gui process gently (if needed)
bool status = proc.CloseMainWindow();
// wait for process to close gently
bool status = proc.WaitForExit(killTimeMS);
// force close (kill) process
proc.Kill();
If you implement a "no more than one" rule (which is well-documented, as you point out) and then implement the periodic crash-checker, that should be sufficient to ensure that one and only one copy is running.
In fact, the periodic process doesn't even have to check for a crash. It can just fire up an instance, which will immediately exit if another instance is already running, thanks to whatever "no more than one" mechanism you implement. This has the added benefit of avoiding a possible race-condition between detecting a dead process and starting a new one.
You have a few options. The first is checking for a running process using the Process class. I got this from a Microsoft site, but it looks like it works:
public bool IsProcessRunning(string name)
{
//here we're going to get a list of all running processes on
//the computer
foreach (Process clsProcess in Process.GetProcesses())
{
if (clsProcess.ProcessName.StartsWith(name))
{
//process found so it's running so return true
return true;
}
}
//process not found, return false
return false;
}
You could also use interprocess communications. This is something we do in house. We have a watcher application that sends a message to a service being monitored. If the service doesn't return an ACK in a timeout period, we attempt to restart it.
I suggest you to check if your application is in the list of running processes:
System.Diagnostics.Process.GetProcesses();
I have a simple .exe that needs to be running continuously.
Unfortunately, sometimes it crashes unexpectedly, and there's nothing that can be done for this.
I'm thinking of like a C# program that scans the running application tree on a timer and if the process stops running it re-launches it... ? Not sure how to do that though....
Any other ideas?
It's fairly easy to do that, but the "crashes unexpectedly, and there's nothing that can be done for this" sounds highly suspect to me. Perhaps you mean the program in question is from a third party, and you need to work around problems they can't/won't fix?
In any case, there's quite a bit of sample code to do exactly what you're talking about.
The first solution would be to fix your EXE, so it does not crash. If you can not fix it now, you probably need to add exception handling, so you can catch the exception, and not close the EXE.
Second solution is to write simple guard programm that will start your simple .exe and will monitor specific process handle. It will restart your program when it closes.
easiest way is to have you program see if an instance of itself is running and exit if it is. Set up a scheduled task to run it every couple of minutes.
class Program
{
static void Main(string[] args)
{
if (IsRunning())
{
return;
}
else
{
for (int x = 0; x < 10; x++)
{
//Do Stuff
System.Threading.Thread.Sleep(1000);
}
}
}
private static bool IsRunning()
{
Process[] P = Process.GetProcessesByName( Process.GetCurrentProcess().ProcessName ) ;
return P.Count() > 1;
}
}
One trick occasionally employed by malware in days past was to have two processes that each monitor the currently running processes and restart the other process if it is terminated.
The System.Diagnostics namespace has classes which can help, particularly "Process".
For example
static Process[] Process.GetProcesses()
returns a list of all the currently running processes.
If your other process is not in this list, you just restart it with, for example
Process.Start()
Your program needs to initially start your target process itself (with Process.Start), then simply wait for it to terminate (with WaitForExit on object that is returned by Process.Start()). After that whole procedure is repeated.
This way you'd be sure that you are watching the process you are interested in, and you don't need to poll process list at all.
Process.Start() and WaitForExit() usage example.