I am creating a windows service app which will run in background and check xyz.exe is running or not , if app is closed then after some interval of time it will open the app automatically
I am using a timer inside the service app but some how my app is opening in background instead of foreground, can some one help what's gone wrong here
Here is my code in windows service.exe :
protected override void OnStart(string[] args)
{
WriteToFile("Service is started at " + DateTime.Now);
timer.Elapsed += new ElapsedEventHandler(OnElapsedTime);
timer.Interval = 15000; //number in milisecinds
timer.Enabled = true;
}
private void OnElapsedTime(object source, ElapsedEventArgs e)
{
Process[] processes = Process.GetProcessesByName("xyz");
if (processes.Length == 0)
{
WriteToFile("xyz.exe is closed at " + DateTime.Now);
try
{
var p = Process.Start(#"C:\MyAPP\xyz.exe");
p.StartInfo.WindowStyle = ProcessWindowStyle.Maximized;
}
catch(Exception exc)
{
WriteToFile("exception at " + exc);
}
}
else
{
WriteToFile("xyz.exe is Running at " + DateTime.Now);
}
}
Related
I am newbie to windows service and following is what I am trying. The System.Timers.Timer timer1_Elapsedget fired only when I am debugging but when I went for installation nothing get happen. I don't think if I am missing but still I would like to have suggestion/advice from experts and gurus.
protected override void OnStart(string[] args)
{
eventLog1.WriteEntry("myTestService service started on " + DateTime.Now.ToString());
//System.Diagnostics.Debugger.Launch();
double processHour = Convert.ToDouble(ConfigurationManager.AppSettings["ProcessHour"]);
DateTime dtStartDateTime = DateTime.Today.AddHours(processHour);
DateTime dtNow = DateTime.Now;
if (dtNow.Hour>= processHour)
{
dtStartDateTime = dtStartDateTime.AddDays(1);
}
System.TimeSpan diff = dtStartDateTime.Subtract(dtNow);
timer1.Interval = diff.TotalMilliseconds;
this.timer1.Elapsed += timer1_Elapsed;
this.timer1.Start();
eventLog1.WriteEntry("myTestService service exit from onStart at" + DateTime.Now.ToString());
}
private void timer1_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
timer1.Stop();
eventLog1.WriteEntry("myTestService timer1_Elapsed begin on " + DateTime.Now.ToString());
/*some logic*/
}
I am not an experienced programmer so any advice/guidance/examples would be appreciated! I have a windows form application in C# (.Net framework 4.5) that is replacing a windows service (issues with the Session0 variable were encountered). The application needs to open a process, (I'll be using Notepad as an example) and check every 5minutes whether Notepad is still open. If Notepad is not open, the form application must open an instance of it. The application must stop a user from opening another instance of Notepad, if it is already open. My coding currently closes all instances of Notepad. I simply need the application to stop a second instance of Notepad to be opened. The problem is that the user is not allowed to interact with the application at all, as you will note in the coding the user doesn't even see the form. Here is my coding thus far:
private void Form1_Load(object sender, EventArgs e)
{
this.ShowInTaskbar = false;
this.Visible = false;
//handle Elapsed event
myTimer.Tick += new EventHandler(OnElapsedTime);
//This statement is used to set interval to 5 minute (= 300,000 milliseconds)
myTimer.Interval = 60000;//300000;
//enabling the timer
myTimer.Enabled = true;
WatchForProcessStart("Notepad.exe");
}
private void OnElapsedTime(object source, EventArgs e)
{
bool status = IsProcessOpen("notepad");
if (status == true)
{
//TraceService("Notepad is already open" + DateTime.Now);
}
else
{
Process process = new Process();
process.StartInfo.FileName = "notepad.exe";
process.EnableRaisingEvents = true;
process.StartInfo.WindowStyle = ProcessWindowStyle.Normal;
process.Start();
//TraceService("Notepad opened" + DateTime.Now);
}
}
public bool IsProcessOpen(string procName)
{
System.Diagnostics.Process[] proc = System.Diagnostics.Process.GetProcessesByName(procName);
if (proc.Length > 0)
{
return true;
}
else
{
return false;
}
}
private ManagementEventWatcher WatchForProcessStart(string processName)
{
string queryString =
"SELECT TargetInstance" +
" FROM __InstanceCreationEvent " +
"WITHIN 10 " +
" WHERE TargetInstance ISA 'Win32_Process' " +
" AND TargetInstance.Name = '" + processName + "'";
// The dot in the scope means use the current machine
string scope = #"\\.\root\CIMV2";
// Create a watcher and listen for events
ManagementEventWatcher watcher = new ManagementEventWatcher(scope, queryString);
watcher.EventArrived += ProcessStarted;
watcher.Start();
return watcher;
}
private void ProcessStarted(object sender, EventArrivedEventArgs e)
{
ManagementBaseObject targetInstance = (ManagementBaseObject)e.NewEvent.Properties["TargetInstance"].Value;
string processName = targetInstance.Properties["Name"].Value.ToString();
bool status = IsProcessOpen("notepad");
if (status == true)
{
System.Diagnostics.Process.Start("cmd.exe", "/c taskkill /IM notepad.exe");
}
else
{
Process process = new Process();
process.StartInfo.FileName = "notepad.exe";
process.EnableRaisingEvents = true;
process.StartInfo.WindowStyle = ProcessWindowStyle.Normal;
process.Start();
}
}
Wrap it up in a Mutex
var mutexId = "MyApplication";
using (var mutex = new Mutex(false, mutexId))
{
if (!mutex.WaitOne(0, false))
{
MessageBox.Show("Only one instance of the application is allowed!", "Info", MessageBoxButtons.OK, MessageBoxIcon.Hand);
return;
}
// Do scome work
}
If you want to restrict it to one instance per machine, the mutexId needs to be prefixed with Global\
I'm making some Windows Services in c# and i need to read some variables from a config file like files and paths. I also have a variable that controls (it should) the timer interval. The problem is, every time a change data in the config file, that data is not fetched and, for example, if i change the file name i get an error saying that the file does not exist (and i checked the name and the path) or if i change the time interval nothing happens. Can someone help me please?
System.Timers.Timer timer;
CallWebServices call;
int time;
public Planview_SEB_Pervasive()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
call = new CallWebServices();
startPervasive();
}
protected override void OnStop()
{
timer.Enabled = false;
call.InsertLog("PV/S&B Win Service", "Serviço parado", "");
}
private void startPervasive()
{
try
{
try
{
//Vai buscar o tempo ao app.config
time = Convert.ToInt32(ConfigurationManager.AppSettings.Get("TimeElapsedInMinutes"));
}
catch (Exception ex)
{
//Em caso de falha ficam 5 minutos
call.InsertLog("PV/S&B Win Service StartPervasive (time)", ex.Message, "");
time = 5;
}
this.timer = new System.Timers.Timer();
timer.Enabled = true;
timer.AutoReset = true; //Necesário para que o srviço se repita
timer.Interval = 1000 * 60 * time; //Cálculo para minutos
timer.Elapsed += new ElapsedEventHandler(Elapsed);
}
catch (Exception ex)
{
call.InsertLog("PV/S&B Win Service StartPervasive", ex.Message, "");
OnStop();
}
}
protected void Elapsed(Object sender, ElapsedEventArgs e)
{
try
{
timer.Interval = Convert.ToInt32(ConfigurationManager.AppSettings.Get("TimeElapsedInMinutes"));
StartProcess();
}
catch (Exception ex)
{
call.InsertLog("PV/S&B Win Service Elapsed", ex.Message, "");
}
}
private static void StartProcess()
{
try
{
string directory = ConfigurationManager.AppSettings.Get("WorkingDirectory");
string file = ConfigurationManager.AppSettings.Get("FileToRun");
//Execução dos processo (ficheiro)
Process process = new Process();
process.StartInfo.WorkingDirectory = directory;
process.StartInfo.FileName = directory + #"\" + file;
process.StartInfo.Arguments = "";
process.StartInfo.UseShellExecute = false;
process.StartInfo.WindowStyle = ProcessWindowStyle.Normal;
process.StartInfo.CreateNoWindow = false;
process.StartInfo.RedirectStandardOutput = false;
process.Start();
}
catch (Exception ex)
{
throw ex;
}
}
You could implement a FileSystemWatcher that monitors the directory where the app.config is stored in. When it is updated you will get an event in your application notifying you that something has changed. When that occurs you can reload the app.config and refresh your values.
Link: FileSystemWatcher Class
I'm trying to execute some Python scripts from my WPF app. The scripts are generating the log files and the code in the Tick event is reading them and displaying that as it is in a textbox.
My issue here is that, that LaunchProcess fires successfully, but the UI freezes. I have an indefinite progress bar, which too does not start animating. I'm a beginner with WPF and there is something very small I have to do to get this code working. I'm not getting any error/warnings. The scripts run fine and in the end I get to know the result too. But during the run, the UI of my app freezes.
private void LaunchProcess(string paramStr)
{
Process myProcess = new Process();
StartProgressBar();
try
{
dispatcherTimer = new DispatcherTimer();
dispatcherTimer.Tick += new EventHandler(dispatcherTimer_Tick);
dispatcherTimer.Interval = new TimeSpan(0, 0, 0);
dispatcherTimer.Start();
myProcess.StartInfo.UseShellExecute = false;
// You can start any process
myProcess.StartInfo.FileName = "C:\\Python32\\python.exe";
myProcess.StartInfo.Arguments = "\""+paramStr+"\"";
myProcess.StartInfo.CreateNoWindow = true;
myProcess.StartInfo.RedirectStandardOutput = true;
myProcess.StartInfo.RedirectStandardError = true;
myProcess.Start();
myProcess.WaitForExit();
// 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.
dispatcherTimer.Stop();
}
catch
{
MessageBox.Show("Process Launch Failed!!", "Failure", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
private void dispatcherTimer_Tick(object sender, EventArgs e)
{
//txtOutPut.Text = "";
txtOutPut.Text += "\n" + DateTime.Now.ToString();
if (File.Exists(scriptPath+"\\log.txt"))
{
//File.Copy("C:\\FlashAuto\\Execution_Logs\\log.txt", "C:\\FlashAuto\\Temp\\log.txt", true);
TextReader readLogs = new StreamReader(scriptPath + "\\log.txt");
string line = readLogs.ReadLine();
while (line != null)
{
txtOutPut.Text += "\n" + line;
line = readLogs.ReadLine();
txtOutPut.ScrollToEnd();
}
//CountLines = txtExecLog.LineCount - 1;
readLogs.Close();
// Forcing the CommandManager to raise the RequerySuggested event
txtOutPut.ScrollToEnd();
CommandManager.InvalidateRequerySuggested();
readLogs.Dispose();
}
else
{
txtOutPut.Text += "log file not found at: " + DateTime.Now.ToString();
}
}
In case you call LaunchProcess from the UI thread it will obviously be blocked at myProcess.WaitForExit().
You might simply remove the myProcess.WaitForExit() and dispatcherTimer.Stop() calls from the launch method and check if the process is still running in the timer Tick handler.
private void dispatcherTimer_Tick(object sender, EventArgs e)
{
if (myProcess.WaitForExit(0)) // check with timeout zero
{
dispatcherTimer.Stop();
}
... // all your code
}
Calling LaunchProcess method asynchronously would resolve your UI Freeze Issue
public void LaunchProcessAsynchrousCall(string paramStr)
{
ThreadStart displayContentHandler = delegate()
{
LaunchProcess(paramStr)
};
Thread thread = new Thread(displayContentHandler);
thread.IsBackground = true;
thread.Start();
}
I'm trying to create a windows service that will monitor and update an app (winform) and if it's stops or it's not running should start it. But it should run the app as current console user.
My problem it's that it starts the form with network service credentials so it's unavailable for the current user.
protected override void OnStart(string[] args)
{
if (!GetProcessList())
{
Process p = new Process();
p.EnableRaisingEvents = true;
p.Exited += new EventHandler(p_Exited);
StartProcces();
}
else
{
eventLog1.WriteEntry("Process is running");
}
}
void p_Exited(object sender, EventArgs e)
{
StartProcces();
}
static void StartProcces()
{
System.Diagnostics.ProcessStartInfo myProcess = new System.Diagnostics.ProcessStartInfo(#Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName) + "\\WmiMonClient.exe");
myProcess.WorkingDirectory = System.Reflection.Assembly.GetEntryAssembly().Location;
//set environment path
try
{
System.Diagnostics.Process.Start(myProcess);
}
catch (Exception ex)
{
}
}
private static bool GetProcessList()
{
bool proccesIsRunning = false;
Process[] processlist = Process.GetProcesses();
foreach (Process theprocess in processlist)
{
if (theprocess.ProcessName == "WmiMonClient.exe")
{
proccesIsRunning = true;
}
}
return proccesIsRunning;
}
protected override void OnStop()
{
}
One way to attack this might be to create a Scheduled Task (using Windows Scheduler) that executes your code above. If it does, it just starts it up again.
This has the advantage of already running the user context, and not having to consider that from a windows service.