I try to create a windows service which automatically startsup.
I am able to install and deinstall the service. If I try to start it, I get following error message: "Der Dienst antwortete nicht rechtzeitig auf die Start- oder Steueranfrage". (I try to translate) "The service don't respont in time on start or control request".
Here is my poor code
public class LisaServerService: System.ServiceProcess.ServiceBase
{
private Program lisaServerServiceProgram;
public static string LisaServiceName = "LISA-ServerService";
[STAThread]
public static void Main(string[] args)
{
LisaServerService lisaServerService = new LisaServerService();
if (Environment.UserInteractive)
{
lisaServerService.OnStart(args);
Console.WriteLine("I am a service. Normally you can't see the console... just ignore me");
Console.ReadLine();
lisaServerService.OnStop();
}
else
{
ServiceBase.Run(lisaServerService);
}
}
public LisaServerService()
{
InitializeComponent();
}
private void InitializeComponent()
{
this.CanShutdown = true;
this.ServiceName = "LISA - ServerService";
this.CanPauseAndContinue = true;
this.lisaServerServiceProgram = new Program();
}
protected override void OnStart(string[] args)
{
lisaServerServiceProgram.Start(null);
base.OnStart(args);
}
protected override void OnStop()
{
lisaServerServiceProgram.Stop();
base.OnStop();
}
protected override void OnShutdown()
{
OnStop();
base.OnShutdown();
}
}
Program.cs
public class Program
{
public Program()
{
Logger.LogLevel = LogLevel.Information;
Logger.LogRange = LogRange.Write;
Logger.Log("Logger initialized");
}
public void Start(string[] args)
{
DatabaseHandler.StartDatabase();
NetworkHandler.StartNetwork();
Logger.Log("Service started");
}
if I run the service as a console program, it works fine.
So the db connection + logger are working fine too. (Also within < 10ms)
If you're running the service in interactive mode it's waiting for the console here:
if (Environment.UserInteractive)
{
lisaServerService.OnStart(args);
Console.WriteLine("I am a service. Normally you can't see the console... just ignore me");
Console.ReadLine();
...
That is likely preventing the service from responding properly to indicate it is started.
Related
I'm doing a base project for windows services with the posibility to debug the Windows Service in console and I'm havig a problem with install.
I get the error 1053. InvalidOperationException. The service did not respond in a timely maner. I have done in the past Windows Services following this practices and I have never seen this error.
I have beetn trying with console or without it and always fails. I don't know what could be the cause of the error because the service is extremly simple with no blocking operations or something like that.
The exception is thrown in AfterInstall event in the installer.
MainClass
public class Program
{
enum RunMode { NONE, INSTALL, UNINSTALL, CONSOLE, RETHROW};
static int Main(string[] args)
{
RunMode runMode = GetRunMode(args);
try
{
switch (runMode)
{
case RunMode.INSTALL:
SelfInstaller.Install(args);
break;
case RunMode.UNINSTALL:
SelfInstaller.Uninstall(args);
break;
case RunMode.CONSOLE:
RunConsoleMode();
break;
case RunMode.RETHROW:
RunService();
break;
default:
break;
}
return 0;
}
catch (Exception ex)
{
if (runMode == RunMode.RETHROW) throw;
Console.WriteLine($"Error Running: {ex.Message}");
return -1;
}
}
private static RunMode GetRunMode(string[] args)
{
foreach (string arg in args)
{
switch (arg)
{
case "-i":
case "-install":
return RunMode.INSTALL;
case "-u":
case "-uninstall":
return RunMode.UNINSTALL;
case "-c":
case "-console":
return RunMode.CONSOLE;
case "-r":
return RunMode.RETHROW;
default:
Console.WriteLine($"Argument not expected {string.Join("|", args)}");
break;
}
}
return RunMode.NONE;
}
private static void RunService()
{
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[] { new WinService() };
ServiceBase.Run(ServicesToRun);
}
private static void RunConsoleMode()
{
var srv = new WinService();
Console.WriteLine("Starting ...");
srv.StartUp();
Console.WriteLine("System running; press any key to stop");
Console.ReadKey(true);
srv.ShutDown();
Console.WriteLine("System stopped");
Console.ReadLine();
}
}
Windows Service
internal class WinService : ServiceBase
{
#region Windows Service Lifecycle
protected override void OnStart(string[] args)
{
base.OnStart(args);
StartUp();
}
protected override void OnStop()
{
ShutDown();
}
#endregion
#region Start and StopMethods
public void StartUp()
{
Console.WriteLine($"{DateTime.Now:yyyy-MM-dd HH:mm:ss} - Service Started");
}
public void ShutDown()
{
Console.WriteLine($"{DateTime.Now:yyyy-MM-dd HH:mm:ss} - Service Stopped");
}
#endregion
}
Service Installer
[RunInstaller(true)]
public sealed class MyServiceInstallerProcess : ServiceProcessInstaller
{
public MyServiceInstallerProcess()
{
this.Account = ServiceAccount.LocalSystem;
}
}
[RunInstaller(true)]
public sealed class MyServiceInstaller : ServiceInstaller
{
public MyServiceInstaller()
{
this.Description = ConfigurationManager.AppSettings["ServiceDescription"];
this.DisplayName = ConfigurationManager.AppSettings["ServiceDisplayName"];
this.ServiceName = ConfigurationManager.AppSettings["ServiceName"];
this.StartType = System.ServiceProcess.ServiceStartMode.Automatic;
this.AfterInstall += ServiceInstaller_AfterInstall;
this.BeforeUninstall += ServiceInstaller_BeforeUninstall;
}
void ServiceInstaller_AfterInstall(object sender, InstallEventArgs e)
{
using (ServiceController sc = new ServiceController(this.ServiceName))
{
sc.Start();
}
}
void ServiceInstaller_BeforeUninstall(object sender, InstallEventArgs e)
{
using (ServiceController sc = new ServiceController(this.ServiceName))
{
if (sc.Status == ServiceControllerStatus.Running)
{
sc.Stop();
}
}
}
}
I have a windows service that is having trouble executing the Onstart() method after installing it and running it from the service menu.I'm logging everything that is happening at every step of the execution to see where the problem is. But there is no error, it logs and runs fine in the main method , up until the service is actually called to run and then it just does nothing.
It's interesting to note that it doesn't have ANY problem running in debug.
My program class(starting point) from which the service is called :
public class Program
{
private static Container _container;
private static ILogger<Program> _logger;
/// <summary>
/// The main entry point for the application.
/// </summary>
private static void Main()
{
_container = SimpleInjectorContainer.Build(registerConfig: true, useThreadScopedLifestyle: true);
SimpleInjectorContainer.LoggAndVerify(_container);
using (ThreadScopedLifestyle.BeginScope(_container))
{
try
{
_logger = _container.GetInstance<ILogger<Program>>();
_logger.LogInformation("Test - Works");
VerifyConfiguration();
}
catch (Exception ex)
{
var logger = _container.GetInstance<ILogger<Program>>();
logger.LogError(ex, "Configuration is not valid");
throw;
}
if (Environment.UserInteractive)
{
RunDebug();
}
else
{
System.Diagnostics.Debugger.Launch();
_logger.LogInformation("It's Here 49");
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
_container.GetInstance<SenderService>()
};
_logger.LogInformation("It's Here 56");
//up until here its fine, but it doesn't run the next line
ServiceBase.Run(ServicesToRun);
_logger.LogInformation("It's Here 58");
}
}
}
private static void RunDebug()
{
var senderService = _container.GetInstance<SenderService>();
senderService.TestStart();
Console.WriteLine("Sender Started Debug");
Console.ReadLine();
senderService.TestStop();
}
private static void VerifyConfiguration()
{
var configValidator = _container.GetInstance<IConfigurationValidator>();
configValidator.VerifyOperatorPrefixNumbers();
configValidator.VerifyConfiguration();
configValidator.VerifyOperators();
}
}
My actual service :
public partial class SenderService : ServiceBase
{
private readonly Container container;
private readonly ILogger<SenderService> logger;
private readonly ISmsHandlerConfig config;
private readonly IConfigurationValidator configValidator;
public SenderService(
Container container,
ILogger<SenderService> logger,
ISmsHandlerConfig config,
IConfigurationValidator configValidator)
{
this.InitializeComponent();
this.container = container;
this.logger = logger;
this.config = config;
this.configValidator = configValidator;
}
public void TestStart()
{
Console.WriteLine($"Starting {ServiceName} service");
this.OnStart();
}
public void TestStop()
{
Console.WriteLine($"Stopping {ServiceName} service");
this.OnStop();
}
protected void OnStart()
{
try
{
this.logger.LogInformation($"{this.ServiceName} starting");
SmsHandlerAction();
}
catch (Exception ex)
{
this.logger.LogError(ex, $"Error starting service {this.ServiceName}");
throw;
}
}
protected override void OnStop()
{
try
{
this.Dispose();
this.logger.LogInformation($"{this.ServiceName} stopped");
}
catch (Exception ex)
{
this.logger.LogError(ex, $"Error stopping service {this.ServiceName}");
}
}
private void SmsHandlerAction()
{
while (true)
{
this.logger.LogInformation($"{this.ServiceName} started");
using (ThreadScopedLifestyle.BeginScope(this.container))
{
var smsSenderService = this.container.GetInstance<ISmsSenderService>();
var sendResult = smsSenderService.SendSms(this.container);
// Wait if there are not messages for sending
if (!sendResult && this.config.IdleTimeMiliseconds != 0)
{
Thread.Sleep(this.config.IdleTimeMiliseconds);
}
}
}
}
}
this is what is logged:
2019-02-12 18:02:18.7972 INFO Test - Works
2019-02-12 18:02:20.6370 INFO It's Here 49
2019-02-12 18:02:20.6410 INFO It's Here 56
and after I stop the service :
2019-02-12 18:02:35.7375 INFO SenderService stopped
2019-02-12 18:02:35.7375 INFO It's Here 58
It missing the this.logger.LogInformation($"{this.ServiceName} starting"); part.
It doesn't log the line in the onstart method , because it never actually executes, I checked if the service was running, but just failed to log and that is not the case.
My IDE is VS 2017, OS is Win 7, DI library is SimpleInjector 4.0.12.
I know about a similar question asked on stackoverfllow(this) but I don't see how it solves my problem.
Also my event viewer doesn't log any problems also, only information about it starting successfully.
I'm pretty lost so any guidance will be of help.
I found the problem, it was because I removed the override on the OnStart().
My application is not firing the event AfterSessionComplete. Code Below
fiddler.cs
namespace proj
{
public static class Fiddler
{
public static void start()
{
startProxy();
}
public static void startProxy()
{
FiddlerApplication.AfterSessionComplete += FiddlerApplication_AfterSessionComplete;
FiddlerApplication.Startup(8888, true, true, true);
}
public static void FiddlerApplication_AfterSessionComplete(Session sess)
{
//Working aftersessioncomplete
}
}
}
Service1.cs
namespace Proj
{
public partial class Service1 : ServiceBase
{
public Service1()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
Fiddler.start();
}
protected override void OnStop()
{
}
internal void TestStartupAndStop(string[] args)
{
this.OnStart(args); //use to debug
//For commandLine
}
}
}
program.cs
namespace Proj
{
static class Program
{
static void Main(string[] args)
{
if (Environment.UserInteractive)
{
Service1 service1 = new Service1();
service1.TestStartupAndStop(args);
}
else
{
}
}
}
}
I'm creating a windows service but I was facing a debugging issue, that's why I use the console application debug to check my code working or not.
I added break point at aftersessioncomplete event when I get to know that FiddlerApplication.AfterSessionComplete is not firing. It stops the application without going on public static void FiddlerApplication_AfterSessionComplete(Session sess)
Anyone can help? or faced same issue?
After Session cannot fire in window service because of the Certificate popup the certificate as for GUI which windows service cannot provide so the code stuck at certificate installation and not firing after session events.
To work out with this one keep in mind to use console app and hide console app after installation of certificate
How do I convert a command prompt app to a windows service? So far this is what I have, but when I try to install it with InstallUtil.exe I'm received an error:
No public installers with the RunInstallerAttribute.Yes attribute could be found in the ....
I didn't know I had to create an installer class and I'm not sure how to go about this. Can someone help me by telling me how to write an installer class so that I can install my app as a windows service?
class Program
{
public const string ServiceName = "ProcessingApp";
public class Service : ServiceBase
{
public Service()
{
ServiceName = Program.ServiceName;
}
protected override void OnStart(string[] args)
{
Program.Start(args);
}
protected override void OnStop()
{
Program.Stop();
}
}
private static void Start(string[] args)
{
// onstart code here
StartCode();
}
private static void Stop()
{
// onstop code here
ServiceController service = new ServiceController(ServiceName);
try
{
TimeSpan timeout = TimeSpan.FromMilliseconds(100000);
service.Stop();
service.WaitForStatus(ServiceControllerStatus.Stopped, timeout);
}
catch
{
}
}
static void Main(string[] args)
{
if (!Environment.UserInteractive)
// running as service
using (var service = new Service())
ServiceBase.Run(service);
else
{
// running as console app
Start(args);
Console.WriteLine("Press any key to stop...");
Console.ReadKey(true);
Stop();
}
For that to work, you need to have a class that inherits from System.Configuration.Install.Installer in System.Configuration.Install.dll. TThe constructor should configure a ServiceProcessInstaller and a ServiceInstaller, and add them both to the Installers collection - setting the Account, StartType, ServiceName, Description, etc.
MSDN has an example: https://msdn.microsoft.com/en-us/library/system.serviceprocess.serviceprocessinstaller(v=vs.110).aspx
This is my main:
static class Program
{
static void Main()
{
//Debugger.Launch();
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new Service1()
};
ServiceBase.Run(ServicesToRun);
}
}
And this is my Service1() code:
public partial class Service1 : ServiceBase
{
public Service1()
{
Thread messageThread = new Thread(new ThreadStart(Messaggi.Check));
messageThread.Start();
bool checkGruppoIndirizzi = true;
for (; ; )
{
SediOperative.Check();
Autisti.Check();
AutistiVeicoli.Check();
StatiVega.Check();
int res = Ordini.Check();
if (res == 0) AssegnazioniVega.Check();
Thread.Sleep(10000);
}
}
protected override void OnStart(string[] args)
{
}
protected override void OnStop()
{
}
}
First thing is I don't know if launching two threads in that way is a good thing to do, but the real problem is the program run fine inside Visual Studio but after installation (I've created a setup project using InstallShield) I try to start my service from the windows service panel and I get:
Error 1053: The service did not respond to the start or control request in a timely fashion
The problem you have is that your service will be started sucessfully after the susyem has called the Start method and it has sucessfully returned. Given that you have an infinite loop in the constructor, the system is saying to itself something like "Can't even create the this let alone call start. I'm giving up.'
Your code should be refactored along these lines:
public partial class Service1 : ServiceBase
{
public Service1()
{
}
private Thread messageThread;
private Thread otherThread;
private bool stopNow;
protected override void OnStart(string[] args)
{
this.stopNow = false;
this.messageThread = new Thread(new ThreadStart(Messaggi.Check));
this.messageThread.Start();
this.otherThread = new Thread(new ThreadStart(this.StartOtherThread));
this.otherThread.Start();
}
private void StartOtherThread()
{
bool checkGruppoIndirizzi = true;
while (this.stopNow == false)
{
SediOperative.Check();
Autisti.Check();
AutistiVeicoli.Check();
StatiVega.Check();
int res = Ordini.Check();
if (res == 0) AssegnazioniVega.Check();
for (int 1 = 0; i < 10; i++)
{
if (this.stopNow)
{
break;
}
Thread.Sleep(1000);
}
}
}
}
protected override void OnStop()
{
this.stopNow = true;
this.messageThread.Join(1000);
this.otherThread.Join(1000);
}
}
And yes, starting stuff on Threads is exactly the way to do it! You'll have to have some way of stopping them in the Stop() method. (The code above is air code so don't trust it.) for the 'otherThread' I've got it checking a bool and exiting when the bool is set. the thread.Join is just a tidy-up which isn't strictly necessary, but is good housekeeping I think.
Cheers -