Self-install of WInService - c#

I've googled this one
but when i'm trying to apply it i get an error. So install/uninstall works fine, but service itself just doesn't start and after timeout it says that service doesn't respond. I don't know why. When i'm attaching to process it even doesn't enter into Main() method, static constructors and so on. I've used this addon for attach.
public static void Main()
{
AppDomain.CurrentDomain.UnhandledException += OnException;
if (Environment.UserInteractive)
{
AskUserForInstall();
}
else
{
ServiceBase.Run(new NotificatorService());
}
}
Service is also very simple:
using System.ServiceProcess;
using System.Windows;
namespace AZNotificator
{
public partial class NotificatorService : ServiceBase
{
static NotificatorService()
{
int x = 5;
}
public NotificatorService()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
MessageBox.Show("Hello");
}
protected override void OnStop()
{
}
}
}

You can not call MessageBox.Show("Hello"); from the windows service since the service does not have the GUI.
If you want to do some interaction from the windows service have a look at this article
http://msdn.microsoft.com/en-us/library/ms683502(VS.85).aspx
So remove MessageBox.Show("Hello"); from your OnStart method and your service should start just fine.

Related

listen to event raised from application running in windows service

I am trying to listen to event which is raised from application running under a windows service. Below is sample code to demonstrate as what I am after ...
Separate Class library code(classlibrary1.dll)
namespace ClassLibrary1
{
public class Class1 : MarshalByRefObject
{
public event TestServiceDel TestEvent;
TestEventArgs args1 = new TestEventArgs
{
Data = "Hello Buddy ... How Is Life!!!!!"
};
public void RaiseEvent()
{
if (!EventLog.SourceExists("TestService"))
EventLog.CreateEventSource("TestService", "Application");
EventLog.WriteEntry("TestService","Before raising event ...");
if (TestEvent != null)
TestEvent(this, args1);
EventLog.WriteEntry("TestService","After raising event ...");
}
}
Hosted Windows Service (windowsservice1exe)
public partial class Service1 : ServiceBase
{
public Service1()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
System.Threading.Thread.Sleep(1000);
ClassLibrary1.Class1 cs = new ClassLibrary1.Class1();
cs.RaiseEvent();
}
Client application (consoleapp1.exe)
class Program : MarshalByRefObject
{
static void Main(string[] args)
{
Class1 cs = new Class1();
cs.TestEvent += Cs_TestEvent;
Console.ReadLine();
}
private static void Cs_TestEvent(object sender, TestEventArgs args)
{
EventLog.WriteEntry("TestService",args.Data, EventLogEntryType.Information);
Console.WriteLine(args.Data);
}
As you can see, I have tried subclassing MarshalByRefObject for both publisher/subscriber but it's not working. I mean I can see in event log that the events are getting raised but my client application never receives the notification (or) the notification never reaches.
Please let me know how to achieve this.
Since my service and client both running in same machine, I believe I don't need to use Remoting. Right?

Windows service with Nancy does not start host

I have developed a Windows Service whose task is actually to start a host with particular url and port. Below is what I have now.
Program.cs
static void Main()
{
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new WindowsDxService()
};
ServiceBase.Run(ServicesToRun);
}
ProjectInstaller.cs
[RunInstaller(true)]
public partial class ProjectInstaller : System.Configuration.Install.Installer
{
public ProjectInstaller()
{
InitializeComponent();
}
}
WindowsDxService.cs
public partial class WindowsDxService : ServiceBase
{
public WindowsDxService()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
var url = "http://127.0.0.1:9000";
using (var host = new NancyHost(new Uri(url)))
{
host.Start();
}
}
}
Configuration on serviceProcessInstaller1 and serviceInstaller1 in ProjectInstaller.cs [Design] file.
serviceProcessInstaller1
Account=LocalSystem
serviceInstaller1
StartType=Automatic
Library.cs
public class Library : NancyModule
{
public Library()
{
Get["/"] = parameters =>
{
return "Hello world";
};
Get["jsontest"] = parameters =>
{
var test = new
{
Name = "Guruprasad Rao",
Twitter="#kshkrao3",
Occupation="Software Developer"
};
return Response.AsJson(test);
};
}
}
Basically I followed this tutorial which actually shows how to do it with Console application which I succeeded though, but I wanted to have this as Windows Service which actually starts a host with specified port whenever the system starts. The service is started successfully and running but whenever I browse the url in the same system its not showing up the page, which means our basic This webpage is not available message. What else configuration I have to do so as to start the host? Hoping for a help.
You are disposing the host when you start your service. I would suggest something like this:
public partial class WindowsDxService : ServiceBase
{
private Host host;
public WindowsDxService()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
this.host = new NancyHost(...)
this.host.Start();
}
protected override void OnStop()
{
this.host.Stop();
this.host.Dispose();
}
}
You'd probably find it a lot easier to write the service if you used TopShelf library.

Debugging and logging windows service

I am learning basics of windows service. I have created a very simple one.
using System.ServiceProcess;
namespace WindowsServiceBasic
{
public partial class OmerService : ServiceBase
{
public OmerService()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
System.Diagnostics.Debugger.Launch();
WriteLog("START");
}
protected override void OnStop()
{
System.Diagnostics.Debugger.Launch();
WriteLog("STOP");
}
private void WriteLog(string durum)
{
eventLog1.WriteEntry(performanceCounter1.RawValue.ToString());
}
}
}
using System;
using System.IO;
using System.ServiceProcess;
namespace WindowsServiceBasic
{
internal static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
private static void Main()
{
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new OmerService()
};
ServiceBase.Run(ServicesToRun);
}
private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
if (e != null && e.ExceptionObject != null)
{
string createText = e.ToString();
File.WriteAllText(#"c:\omerlog.txt", createText);
}
}
}
}
The first time my service (AServis) starts successfully but when I click the restart it crashes. Since my service is very simple It should have been worked properly. I try to log the error, put try catch but I could not find anything. I am trying to attach process, it debugs stop event but after stop debug suddenly finishes and start process crashes. Could you please help me what is the reason and how can I debug and log error.
Thanks in advance
I saw that it was stuck in
public OmerService()
{
InitializeComponent();
}
I could see the issue adding System.Diagnostics.Debugger.Launch(); statement.
public OmerService()
{
System.Diagnostics.Debugger.Launch();
InitializeComponent();
}
The standard trick I use in this situation is to add a call to System.Diagnostics.Debugger.Break in my start up code. Now, when you start the service as normal (through the Service Control Manager (SCM)), the call to the Break will cause Windows to launch the JIT debugger, which should prompt you to choose the debugger you wish to attach to the process (e.g., Visual Studio), which will then enable you to debug your code as normal.
Also see this: Easier way to debug a Windows service.

Windows service does nothing on production PC

I have an application that schedules jobs using Quartz.Net. It works on my development laptop perfectly both as a winforms application (with start and stop buttons) and as a Windows Services whose OnStart() and OnStop() event code matches the start and stop button code of the winforms application. They're both in the same solution using the same "model" code (in its own project).
If I run the winforms application on the production computer it works perfectly, the jobs are executed according to their schedule as expected. However if I install and run it as a Windows Service on the production PC nothing happens! The jobs do not run.
I have no idea how to debug this. Please let me know if you have any suggestions as to what might be wrong.
Also please let me know what other information I should be providing.
Oh - dev PC is running Windows 7, production PC is running Windows 8.1! Could that be the problem? I built the service by following this tutorial: http://msdn.microsoft.com/en-us/library/zt39148a(v=vs.110).aspx which does not indicate that anything special needs to be done for deploying to Windows 8?
Could this have something to do with environment variables (which I know nothing about)?
Here is some code which may be relevant:
The service:
namespace DataPump
{
public partial class DataPumpService : ServiceBase
{
private TaskManager _taskManager;
public DataPumpService()
{
InitializeComponent();
_taskManager = new TaskManager();
}
protected override void OnStart(string[] args)
{
_taskManager.Go();
}
protected override void OnStop()
{
_taskManager.Stop();
}
}
}
The form code (different project):
namespace DataPump
{
public partial class Form1 : Form
{
private TaskManager _taskManager = new TaskManager();
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
_taskManager.Go(); //Loops infinitely, does not block
label1.Text = "Running...";
}
private void button2_Click(object sender, EventArgs e)
{
label1.Text = "Stopping...";
_taskManager.Stop();
label1.Text = "Idle";
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
_taskManager.Stop();
}
}
}
Selected code from TaskManager code (third project which the first two each reference):
public class TaskManager
{
//...
private IScheduler _scheduler = StdSchedulerFactory.GetDefaultScheduler();
//...
public void Go()
{
if (_scheduler.GetCurrentlyExecutingJobs().Count() == 0)
{
_scheduler.Start();
_scheduler.AddCalendar(CalendarName, MakeSAPublicHolidayCalendar(), false, true);
foreach (DatapumpJob job in JobList)
{
_scheduler.ScheduleJob(MakeJob(job), MakeTriggerCron(job));
}
}
}
//...
public void Stop()
{
foreach (string name in _scheduler.GetCurrentlyExecutingJobs().Select(j => j.JobDetail.Key.Name))
{
_scheduler.Interrupt(new JobKey(name));
}
_scheduler.Shutdown(true);
}
//...
}
Where JobList is a get only property that generates a List<DatapumpJob>where DatapumpJob implements IInterrutableJob but adds common features including a job name which gets use by the three methods beginning Make... which are all private methods within the TaskManager class.
This code is to answer a question from the comments regarding ServiceBase.Run():
Program.cs (auto-generated):
namespace DataPump
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
static void Main()
{
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new DataPumpService()
};
ServiceBase.Run(ServicesToRun);
}
}
}
This turned out to be a network permissions issue. The service was running, it was just unable to access the network drive. So really my question was mi-specified.
After trying this: https://serverfault.com/questions/177139/windows-service-cant-access-network-share we eventually got it to work by setting the service to run as a specific user account on the PC.

Windows Service + read from database

I am new To windows service. I need a windows service that reads an entry from a table from database. I have a CONSOLE APP where I add new project WINDOWS SERVICE. I already have a method that access the database, and other methods. I can put a thread on start that reads the database. Where do I put the thread? ( how can I do that). Where on WINDOWS SERVICE I add those methods? I have the Windows Service like this:
public Service1()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
do
{
thread.start();
bool variab = readFromDatabase (Database table);
}
}
protected override void OnStop()
{
}
I suggest that you create a class in which you do everything you need and create in in the service:
public Service1()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
YourClass cl = new YourClass();
cl.DoWhatYouNeed(...);
}
protected override void OnStop()
{
}
This gives you opportunity to run and test your class separate from service, maybe during debug release.
With windows services usually a method is created to execute the main loop of the service, in a separated thread. Otherwise the service could become unresponsive. For example, you can have a method called MainLoop to execute the service logic. Use the OnStart method only to do the initializing tasks, such as read configuration values or start the threads of the service. And use the OnStop to executing cleaning tasks, stopping threads, etc...
Thread _workerThread;
bool _shouldStop;
public Service1()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
try{
_workerThread = new Thread(new ThreadStart(MainLoop));
_shouldStop = false;
_workerThread.Start();
}
catch{}
}
private void MainLoop()
{
while (!_shouldStop)
{
try{
//your logic here
}
catch{}
}
}
protected override void OnStop()
{
_shouldStop = true;
}
You must put your code or class, which contain data access logic in OnStart method

Categories

Resources