问题
I have developed windows service for checking some services running or not for every two minutes.if the services are not running then start them automatically.
here is my code
public partial class Service1 : ServiceBase
{
public Service1()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
this.CheckServices();
this.ScheduleService();
}
protected override void OnStop()
{
this.Schedular.Dispose();
}
public void CheckServices()
{
log4net.Config.BasicConfigurator.Configure();
log4net.ILog log = log4net.LogManager.GetLogger(typeof(Service1));
try
{
string[] arr1 = new string[] { "CaseWorksCachingService", "Te.Service" };
for (int i = 0; i < arr1.Length; i++)
{
ServiceController service = new ServiceController(arr1[i]);
service.Refresh();
if (service.Status == ServiceControllerStatus.Stopped)
{
service.Start();
}
}
}
catch (Exception ex)
{
log.Error("Error Message: " + ex.Message.ToString(), ex);
}
}
//ScheduleService Method
private Timer Schedular;
public void ScheduleService()
{
try
{
Schedular = new Timer(new TimerCallback(SchedularCallback));
string mode = ConfigurationManager.AppSettings["Mode"].ToUpper();
//Set the Default Time.
DateTime scheduledTime = DateTime.MinValue;
if (mode.ToUpper() == "INTERVAL")
{
//Get the Interval in Minutes from AppSettings.
int intervalMinutes = Convert.ToInt32(ConfigurationManager.AppSettings["IntervalMinutes"]);
//Set the Scheduled Time by adding the Interval to Current Time.
scheduledTime = DateTime.Now.AddMinutes(intervalMinutes);
if (DateTime.Now > scheduledTime)
{
//If Scheduled Time is passed set Schedule for the next Interval.
scheduledTime = scheduledTime.AddMinutes(intervalMinutes);
}
}
TimeSpan timeSpan = scheduledTime.Subtract(DateTime.Now);
//Get the difference in Minutes between the Scheduled and Current Time.
int dueTime = Convert.ToInt32(timeSpan.TotalMilliseconds);
//Change the Timer's Due Time.
Schedular.Change(dueTime, Timeout.Infinite);
}
catch (Exception ex)
{
//Stop the Windows Service.
using (System.ServiceProcess.ServiceController serviceController = new System.ServiceProcess.ServiceController("MyFirstService"))
{
serviceController.Stop();
}
}
}
private void SchedularCallback(object e)
{
//this.WriteToFile("Simple Service Log: {0}");
this.CheckServices();
this.ScheduleService();
}
}
and here is my app.config file
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key ="Mode" value ="Interval"/>
<!-- <add key ="Mode" value ="Interval"/>-->
<add key ="IntervalMinutes" value ="2"/>
</appSettings>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net, Version=2.0.5, Culture=neutral, PublicKeyToken=1b44e1d426115821" />
</configSections>
<!-- Log4net Logging Setup -->
<log4net>
<appender name="FileAppender" type="log4net.Appender.FileAppender,log4net">
<file value="C:\\mylogfile1.txt" />
<!-- the location where the log file would be created -->
<appendToFile value="true" />
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %level %logger - %message%newline" />
</layout>
<filter type="log4net.Filter.LevelRangeFilter">
<levelMin value="INFO" />
<levelMax value="FATAL" />
</filter>
</appender>
<root>
<level value="DEBUG" />
<appender-ref ref="FileAppender" />
</root>
</log4net>
</configuration>
Error: "The Windows Search service on local computer started and then stopped. Some services stop automatically if they are not in use by other services or programs"
回答1:
There may very well be an exception occurring that is causing your service to exit prematurely. That is worth looking into. However, I suspect the actual cause of your problem is that your service is simply exiting immediately after executing the OnStart()
method. Windows services do not automatically stay running. If the OnStart()
method does not kick off a foreground thread that keeps the service running, you will see the exact error that you are receiving. I've tried executing your code in a local console application, and once the OnStart()
method finished, the console application exits.
To keep your service running until it is shutdown, start a foreground thread in the OnStart()
method. The following is a working example.
using System.Threading;
private ManualResetEvent _shutdownEvent = new ManualResetEvent(false);
private Thread _thread;
protected override void OnStart(string[] args)
{
_thread = new Thread(WorkerThreadFunc);
_thread.Name = "My Worker Thread";
_thread.IsBackground = false;
_thread.Start();
}
protected override void OnStop()
{
this.Schedular.Dispose();
this._shutdownEvent.Set();
this._thread.Join(3000);
}
private void WorkerThreadFunc()
{
this.CheckServices();
this.ScheduleService();
// This while loop will continue to run, keeping the thread alive,
// until the OnStop() method is called.
while (!_shutdownEvent.WaitOne(0))
{
Thread.Sleep(1000);
}
}
Nothing else needs to change.
If you want to debug your service, put a call to System.Diagnostics.Debugger.Launch() at the beginning of your OnStart()
method and compile in debug. When you start the service, you will be prompted to start a debugging session. You should be able to set breakpoints and debug normally at that point, assuming you have sufficient privileges on the machine.
HTH
回答2:
The problem with your service is exactly what Matt Davis says in his answer: A service will only stay running if there is a foreground thread spawned in OnStart
. This is what his code is doing. It just creates a thread that does basically nothing but wait, but that's enough to keep the service running.
The rest of your code can stay the same, apart from one thing. Change your ScheduleService
method as follows:
public void ScheduleService()
{
try
{
// Only create timer once
if (Schedular != null)
Schedular = new Timer(new TimerCallback(SchedularCallback));
// Use proper way to get setting
string mode = Properties.Settings.Default.Mode.ToUpper();
...
if (mode == "INTERVAL")
{
// Use proper way to get settings
int intervalMinutes = Properties.Settings.Default.IntervalMinutes;
...
I know that some people may not consider this an answer, but debugging seems to be the key here and thus I'm going to tell you what I found an easy way to debug a service.
Step 1
Extend your service with two methods: One to call OnStart
and one to call OnStop
, as the default methods are protected.
public void DoStart(string[] args)
{
OnStart(xyz);
}
public void DoStop()
{
OnStop();
}
Step 2
Add a simple GUI. A WinForms form without any controls is enough. Extend the constructor to take an instance of your service class. When the form loads "start your service", when it closes, "stop your service". Depending on how you create the form, you may need to manually reference System.Windows.Forms
and System.Drawing
in your project.
Example:
public class ServiceGUI : System.Windows.Forms.Form
{
private MyService _myService;
public ServiceGUI(MyService service)
{
_myService = service;
}
protected override void OnShown(EventArgs e)
{
base.OnShown(e);
_myService.DoStart(null);
}
protected override void OnClosing(CancelEventArgs e)
{
base.OnClosing(e);
_myService.DoStop();
}
}
Step 3
Let your Main
method decide whether to run as a service or as a GUI application. The handy Environment.UserInteractive
property allows you do decide whether the exe was run by some GUI user.
if (Environment.UserInteractive)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new ServiceGUI(new MyService()));
}
else
{
ServiceBase.Run(new ServiceBase[] { new MyService() });
}
What can you do now?
You can start your application as if it were a normal application and actually properly debug, setting breakpoints, inspecting variables etc. Of course I know that you can also attach your debugger to a running process, but in your case you don't have a running process, so this is a good solution to see what the problem is.
Things like your service starting code will probably not work (unless you run Visual Studio as administrator), but that can also be a nice test whether things work when starting your services runs into an error.
来源:https://stackoverflow.com/questions/39014736/windows-service-doesnt-run-at-regular-intervals