As I understand it, the serviceBase.Onstart(args) should recieve arguments that are present in serviceController.start(args).
Here is my service controller implementation
if (serviceController.Status == ServiceControllerStatus.Stopped)
{
try
{
string[] args = {"execute-service"};
serviceController.Start(args);
ServiceManager.WaitForStatusChange(......);
}
catch (InvalidOperationException ex)
{
EventLog.WriteEntry(.....);
return 1;
}
}
Here is my service.cs
protected override void OnStart(string[] args)
{
this.OnStart(args);
this.scheduler.StartScheduler();
}
When I attempt to start my service, the argument "execute-service" is not passed to the main program.cs. I have a logFile that is being created and can see the args are not there.
Looking for some ideas on how to pass the args, as I read online, I am doing it correctly using the servicebase.onstart().
Thoughts on how to debug or fix?
I don't think there is enough information shown here to debug this issue. For comparison, this is what I do in a console application designed to run as a Windows service:
public sealed partial class ServiceMain : ServiceBase
{
// Service startup modes.
private const string DEBUG = #"/d";
private const string INSTALL = #"/i";
private const string UNINSTALL = #"/u";
Then ServiceMain.Main() is set is set as the startup method:
// This is the entry point for this service.
// This method runs on an SCM thread.
public static void Main(string[] args)
{
if (Environment.UserInteractive && args.Length > 0)
{
switch (args[0])
{
// Debug the service as a normal app, presumably within Visual Studio.
case DEBUG:
ServiceMain DebugService = new ServiceMain();
DebugService.OnStart(null);
break;
Which calls the ServiceMain.OnStart() method:
// SCM requests service start using its own thread.
// This method must complete within 10 seconds of it
// starting. Otherwise the SCM diagnoses a hang.
protected override void OnStart(string[] args)
{
this.AppLog = new Log();
AppLog.Information("SCM requested service start.", "ServiceMain.OnStart");
You can see the whole service in context here.
Related
I have developed a C# Windows service to get some datas from DB and process them in an infinite loop. The service was working fine with nothing but loop in it yesterday but today I have finished the development and tried to test it as a Windows service but it keep says Starting and when the green bar is complete it gives me "1053" error. I have checked if there are any logs and my service is inserting logs and even processing Datas but somehow I still get this error.
I have installed the service from my release folder. There is no error on Event Viewer regarding the service. And my service looks like below.
*UPDATE: When I check event viewer I see below messages in a sequence; "Session 1 started", "Ending Session 1" "Machine restart required". I have tried restarting but it didn't make any difference
Program.cs
static class Program
{
static void Main()
{
try
{
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new spService()
};
ServiceBase.Run(ServicesToRun);
}
catch (Exception ex)
{
EventLog.WriteEntry("Application", ex.ToString(), EventLogEntryType.Error);
}
}
}
Service1.cs
public partial class spService: ServiceBase
{
public spService()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
SpPushOperation spo = new SpPushOperation();
spo.StartSpPushOperation();
}
protected override void OnStop()
{
SpPushOperation spo = new SpPushOperation();
spo.StopSpPushOperation();
}
}
SpPushOperation.cs
class SpPushOperation
{
public readonly NLog.ILogger Logger = NLog.LogManager.GetCurrentClassLogger();
public void StartSpPushOperation()
{
try
{
Logger.Info("-------------");
Logger.Info("SpPushOperation Started..");
Logger.Info("-------------");
while(true)
{
//some process in here
}
}
catch(Exception e)
{
Logger.Info("!!!!!!!!!!!!!!");
Logger.Info("Error on getting StartSpPushOperation Error: " + e);
Logger.Info("!!!!!!!!!!!!!!");
}
}
}
Any help would be appreciated. Thanks.
Issue was caused due to using infinite loop in service. To fix this issue instead of using infinite loop start the service with a thread and run for every 60 seconds.
So i've made a small service program, but it won't start.
It installs by itself, but I don't have it in auto-start.
It's on a windows 7, 64 bit system.
When I find it in Services, right click the service and have it start, it times out with the error 1053 after about 30 seconds.
I am running the program as release, and not debug.
Tried to install as local admin and do everything as local admin.
The OnStart() and OnStop() methods are empty with no code, I removed it all to eliminate what it could be.
Tried putting a small logging action that I know works(I use it to create a log file when the install is successful) at the start of OnStart() but it never reaches it.
Help?
Edit:
Here is my Program.cs code:
namespace TestService
{
static class Program
{
// The main entry point for the application.
static void Main()
{
//Install self
SelfInstaller.InstallMe();
}
}
}
Here is my Library.cs:
namespace TestService
{
//Library to store public methods
public static class Library
{
//Method to write to a logfile
public static void WriteLogFile(string Message)
{
StreamWriter sw = null;
try
{
sw = new StreamWriter(AppDomain.CurrentDomain.BaseDirectory + "\\Logfile.txt", true);
sw.WriteLine(DateTime.Now.ToString() + ": " + Message.ToString());
sw.Flush();
sw.Close();
}
catch
{
//empty
}
}
}
}
Here is my Service1.cs:
namespace TestService
{
public partial class Service1 : ServiceBase
{
//Initialize
public Service1()
{
InitializeComponent();
}
//On service start
protected override void OnStart(string[] args)
{
}
//On service stop
protected override void OnStop()
{
}
}
}
It seems like you found a tutorial but followed only half of it.
Your current main() code will install the service every time you try to start it:
static void Main()
{
//Install self
SelfInstaller.InstallMe();
}
So that won't let the ServiceManager know the service has been started - as it isn't.
You need to decide, in main(), whether you want to start, install, uninstall or debug the service. It's common to do so using command-line arguments, where no arguments supplied means "start the service".
How to do this is also shown in that very tutorial.
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
Is it possible to have an application that runs as a service if it is registered as such but if it is double clicked simply starts a regular interactive application?
Yes. You can use the Environment.UserInteractive variable. You will need to create a small wrapper around your service to expose the OnStart() and OnStop() methods since they are protected.
var service = new MyService();
if (Environment.UserInteractive)
{
service.Start(args);
Console.WriteLine("Press any key to stop program");
Console.Read();
service.Stop();
}
else
{
ServiceBase.Run(service);
}
Wrapper Class (Make sure to extend ServiceBase)
public partial class MyService : ServiceBase
{
protected override void OnStart(string[] args)
{
//start code
}
protected override void OnStop()
{
//stopcode
}
public void Start(string[] args)
{
OnStart(args);
}
}
I have a WCF service hosted in a consol application(that also acts as the Windows Service installer), pleas see more here : http://msdn.microsoft.com/en-us/library/ms733069.aspx
This is how the class in the consol application looks like :
public class MyAppWindowsService : ServiceBase
{
public ServiceHost _MyAppClientServiceHost = null;
public ServiceHost _MyAppIntegrationServiceHost = null;
public ServiceHost _MyAppserviceHost = null;
public MyAppWindowsService()
{
// Name the Windows Service
ServiceName = "MyApp Service";
}
public static void Main()
{
ServiceBase.Run(new MyAppWindowsService());
}
private void StopService(ServiceHost serviceHost)
{
if (serviceHost != null)
{
serviceHost.Close();
serviceHost = null;
}
}
private ServiceHost StartService(Type serviceType)
{
ServiceHost serviceHost = null;
// Create a ServiceHost for the CalculatorService type and
// provide the base address.
serviceHost = new ServiceHost(serviceType);
// Open the ServiceHostBase to create listeners and start
// listening for messages.
serviceHost.Open();
return serviceHost;
}
private void StartServices()
{
StopService(_MyAppClientServiceHost);
StopService(_MyAppIntegrationServiceHost);
StopService(_MyAppServiceHost);
_MyAppClientServiceHost = StartService(typeof(MyApp.ServiceImplementation.MyAppClientService));
_MyAppIntegrationServiceHost = StartService(typeof(MyApp.ServiceImplementation.MyAppIntegration));
_MyAppServiceHost = StartService(typeof(MyApp.ServiceImplementation.HL7Service));
}
private void StopServices()
{
StopService(_MyAppClientServiceHost);
StopService(_MyAppIntegrationServiceHost);
StopService(_MyAppHl7ServiceHost);
}
// Start the Windows service.
protected override void OnStart(string[] args)
{
StartServices();
}
protected override void OnStop()
{
StopServices();
}
}
This is made for running in a Windows Service, how do I make so I can run this as a regular selfhost in debug mode(during development)? or do I really have to start a special project to be able to debug this servuce during runtime?
Edit:
I decided to use the existing windows service project but change the main to something like this :
public static void Main()
{
if (Debugger.IsAttached)
{
Console.WriteLine("--- MyApp Services ---");
Console.WriteLine("Starting services...");
Instance.StartServices();
Console.WriteLine("--Finished--");
Console.WriteLine("Press any key to exit");
Console.ReadKey();
Instance.StopServices();
}
else
ServiceBase.Run(new MyAppWindowsService());
}
This is what I do
Solution A
Install a Windows Service using InstallUtil from my Debug\bin folder
Stop and start service using sc start or sc stop
Once service started do Debug > Attach to Process... and attach VS to the service
Solution B
Have a Debugger.Break call on the first line of the OnStart method.
Solution C
Add a temp separate console application that does the same job as your service.