C# Service installer - Upgrade install not stopping service before uninstall - c#

Please review the code below for my project installer BeforeInstall event. The event is being called, as the install completes successfully and will uninstall my service, before installing the new one, but ONLY if I stop the running service before running the installer for the new version.
For some reason, the code in the event is either not stopping the service, or it is not waiting for the service to stop, both of which I am telling it to do before going on to uninstall the service - which again, will complete successfully if the service is not running. It does not appear to even stop the service because after I get the error that resources are in use, I look in services and see that the service is indeed still running. For reference I have also included the AfterInstall event which successfully starts my service.
[EDIT]
It seems like the check to see if the resources are in use is occurring before my event fires. Actually, I've since tried multiple events from the installer and service installer to no avail. Such as OnBeforeUninstall... etc... I've tried multiple methods of shutting down the process including opening cmd.exe and running sc stop on my service. It does not even attempt to run cmd.exe before it checks if resources are in use. Is there a better place to run the service stop code before the resource check happens? I've even thrown it in before Initialize component on the project installer class. Does anyone know when the resource check happens?
void ProjectInstaller_BeforeInstall(object sender, InstallEventArgs e)
{
List<ServiceController> services = new List<ServiceController>(ServiceController.GetServices());
foreach (ServiceController s in services)
{
if (s.ServiceName == this.serviceInstaller1.ServiceName)
{
if(s.Status == ServiceControllerStatus.Running)
{
s.Stop();
s.WaitForStatus(ServiceControllerStatus.Stopped);
}
ServiceInstaller ServiceInstallerObj = new ServiceInstaller();
ServiceInstallerObj.Context = new InstallContext();
ServiceInstallerObj.Context = Context;
ServiceInstallerObj.ServiceName = s.ServiceName;
ServiceInstallerObj.Uninstall(null);
break;
}
}
}
private void ProjectInstaller_AfterInstall(object sender, InstallEventArgs e)
{
using (ServiceController s = new ServiceController(serviceInstaller1.ServiceName))
{
s.Start();
}
}

Related

Unable to Manually Start C# Windows Service

I have created a Windows Service project in Visual Studio Community 2015 on my Windows 10 laptop (upgraded from Windows 7 and fully updated), but I have been unable to successfully start my service manually, and I am unable to force kill the service once it has begun to start. When I attempt to start my service via the Services Console (services.msc), I get the following behavior:
A "Service Control" dialog pops up with a progress bar.
The progress bar fills slowly over the course of 90 seconds.
When the progress bar is full, I receive Error 1053.
The service's state changes to and remains infinitely at "Starting" (Start Pending).
The service can not be stopped by any means besides a forced reboot.
I've come to understand that Error 1053 is the result of a service that is unable to start after 30 seconds. However, there is no possibility of my service taking longer than 30 seconds to start. My OnStart, OnStop, and OnTimer methods are currently as follows:
protected override void OnStart(string[] args)
{
System.Timers.Timer timer = new System.Timers.Timer();
timer.Interval = 10000;
timer.Elapsed += new System.Timers.ElapsedEventHandler(this.OnTimer);
timer.Start();
}
protected override void OnStop()
{
}
public void OnTimer(object sender, System.Timers.ElapsedEventArgs args)
{
}
And my Main method looks like this:
static void Main()
{
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new MyNewService()
};
ServiceBase.Run(ServicesToRun);
}
Strangely, if my service's startup method is set to "Automatic" then the service will indeed start on its own the next time Windows restarts. When it is started automatically, I am able to manually stop the service (this is the only time it will stop manually). However, after successfully stopping it manually, I still cannot re-start it manually. Attempting to do so produces the exact same behavior as described earlier, resulting again in Error 1053.
My service installs without error (via installutil), and I can uninstall without error. However, if I attempt to uninstall my service (via installutil /u) while the service is stuck in "Starting" (Start Pending) mode, the service does not stop, remains as "Starting", and the startup mode switches to "Disabled". Only upon restarting is the service completely removed.
My question:
Why does my service start automatically on Windows startup, but not by any other manual method? (I need it to start automatically, but also be able to manually start and stop it.)
Thank you for your time and expertise.
The issue was Avast anti-virus stopping the service silently. Annoyingly, Avast does not report the service as a virus or a threat of any kind and makes no log of the blocked service. I was able to successfully start and stop my service manually once I had disabled Avast. As a semi-permanent solution, I have added the path to my service to Avast's exceptions list by going to Settings -> Active Protection -> Customize (File System Shield) -> Exclusions, and clicking "Add."
To answer my original question, my service was able to start automatically on Windows startup because it was able to start before Avast was loaded. This led to the strange behavior I observed where I was able to stop it after it had started automatically, but not restart it manually since Avast was now running by that point.
You shoud cleanup service in method OnStop.
You create a timer and never stop it.
private System.Timers.Timer timer;
protected override void OnStart(string[] args)
{
timer = new System.Timers.Timer();
timer.Interval = 10000;
timer.Elapsed += new System.Timers.ElapsedEventHandler(this.OnTimer);
timer.Start();
}
protected override void OnStop()
{
timer.Stop();
timer = null;
}

Windows Service run only on restarting computer

I have created a windows service which I would like to run whenever Windows starts. To run it after boot completion only, I have inserted below code in installer of service:
this.WinSvcInstaller.DelayedAutoStart = true;
The service is made to run immediately after installation using below code:
private void WinSvcInstaller_AfterInstall(object sender, InstallEventArgs e)
{
ServiceController sc = new ServiceController(ServiceName);
sc.Start();
}
where ServiceName is property created in WinSvcInstaller.
Once the service completed whether successfully or unsuccessfully it made to stop using below code automatically:
ProjectInstaller projectInstaller = new ProjectInstaller();
ServiceController serviceController = new ServiceController(projectInstaller.ServiceName);
if (serviceController.Status.Equals(ServiceControllerStatus.Running)
|| serviceController.Status.Equals(ServiceControllerStatus.StartPending))
{
this.Stop();
}
My main problem is that the service doesn't run unless I reboot computer meaning, the service runs only if I restart the computer. If I do shut down and then start computer manually again after the shut down then the service doesn't run. Can anybody please help me why is this happening??? What I am missing?

How can a windows service programmatically restart itself when another windows service is restarted?

I work on windows service project , i want to restart my windows service when Lync Front-End service was restarted
i know how i restart my windows service i use this answer , but i don't know how i restart it when the Front-End Service was restarted
and i know i can check the windows service status by use ServiceController Class
Run this code in your service :
EventLog log = EventLog.GetEventLogs().First(o => o.Log == "Security");
log.EnableRaisingEvents = true;
log.EntryWritten += (s, e) => {p.print(e); };
Write a method for event log
void test(EntryWrittenEventArgs entry)
{
//you can check event log in the log viewer and set
//EventLogEntryType and InstanceId accordingly.
EventLogEntry evntLog=entry.Entry;
if (evntLog.EntryType == EventLogEntryType.SuccessAudit &&
evntLog.InstanceId==123)
{
//Code to restart the service
}
}
I) Topshelf is an open source project for developing Windows Services easily. It will save you time and even if you decide not to use it, you can learn from it's source code.
II) The short answer is you have to poll the status of the other service. There is no (plain) event based mechanism for this.
If you can not make any modifications to the other service then you can poll over it's status by (in a separate Task):
var sc = new ServiceController(serviceName);
status = sc.Status;
And use the answer you've mentioned to restart yours (and again poll in OnStart until the other service get started completely).
But if you can modify the other service then you can use other means like pipes or named mutexes to do that (again needs polling in a separate Task or at OnStart and probably at OnStop).

Why doesn't System.Threading.Timer callback fire?

I'm not using a Windows Form Timer--I'm using a System.Threading.Timer. No exceptions are raised when instantiating the timer, and to my understanding, System.Threading.Timer's do not need to be explicitly started.
I've tried using a System.Timers.Timer (See comments in code) and changing the signature of the callback with no luck. Inside the callback method, I stubbed in some EventLog writes, and not even the first writes to the event log. All I see in the Event Log is MyService.OnStart fired followed by MyService started (these are both from the OnStart event). Why aren't the timer callback events firing?
public partial class MyService : ServiceBase
{
private static System.Threading.Timer timer;
public MyService()
{
InitializeComponent();
if (!System.Diagnostics.EventLog.SourceExists("MyService"))
{
System.Diagnostics.EventLog.CreateEventSource(
"MyService", "MyServiceLog");
}
eventLog1.Source = "MyService";
eventLog1.Log = "MyServiceLog";
}
protected override void OnStart(string[] args)
{
eventLog1.WriteEntry("MyService.OnStart event fired");
// setup timer to poll and execute an event
//Timer timer = new Timer(new TimerCallback(CheckCalls), null, 0, 10000);
try
{
timer = new System.Threading.Timer(new System.Threading.TimerCallback(CheckCalls), null, 0, 10000);
}
catch (Exception ex)
{
eventLog1.WriteEntry(ex.Message + " Stacktrace: " + ex.StackTrace);
}
eventLog1.WriteEntry("MyServicestarted");
GC.KeepAlive(timer);
}
}
and the callback method, CheckCalls:
private static void CheckCalls(object objectState)
{
EventLog eventLog1 = new EventLog("MyServiceLog", "DAVIDWIN7", "MyService");
eventLog1.WriteEntry("MyService is polling");
}
Arg--For some reason when you Build->Clean Solution, then Build->Build Solution, Visual Studio does not rebuild your setup project. I believe my code above works fine, but I had tried many different fixes without explicitly right-clicking the setup project and selecting Build.
I thought Clean Solution would force all projects to be rebuilt on next build???
it's got to be an error with the timer thread writing to the event log.
I got it working on my computer but I replaced all the eventlog with Console.writeline because I didn't want to mess with my event log permissions.
Did you check if the account under which the service is running has access to the eventlog?
Please can you go and download this test application which mirrors exactly the scenario you are talking about:
https://docs.google.com/leaf?id=0Bw_NnV9fhgmgMThjNDgzOTgtODNiOC00NDE1LWEyMTYtNzVhOTMyNzlmZjZk&hl=en&authkey=CMuupNkC
I've just created this. It's a service that effectively uses the same code as you. The only difference is that I have used the toolbox to drag and drop an eventlog on to the service designer - setting the log to 'Application' and the source to 'Service1'.
Open a VS command prompt at the project folder, go to bin\debug and run installutil windowsservice1.exe - specifying some credentials (so you're installing the dev service directly from your bin output folder).
Start the service and monitor the application log - it will write every ten seconds as you expect to see from your code.
Assuming this works on your machine(tm) like it does on my machine(tm) then I would suggest that the problem is the event logging itself, or, horror of horrors - your service isn't running from your build output folder (most of the devs in my team insist on running their dev services from a different folder and then swear when they forget to actually update the binaries when they start debugging it!).
As I suggested in my comment, you really need to be able to attach the debugger to this and breakpoint the callback to verify that it's not getting fired. I never rely on the eventlog for diagnostics messages simply because the log might be full, or permissions might prevent you etc etc - it might be a windows platform component, but it's not as reliable as I would like.
The debugger, however, rarely lies (unless the deployed binaries are out of date ;) ). Compile a debug build of your project and make sure it's the one that is installed in the services list, start it up and then attach directly to the service exe (there's no point trying to attach to [service].vshost.exe - VS cannot auto-attach or host windows services as the only way they can run is via svchost.exe shelling them).
Hope this helps.

How to auto start window service

I have a window service which i developed in c# (vs2008).
please tell me what should i do to make it auto start after installation and also auto start on every time when system gets restarted.
EDIT:
I am using setup & deployment project to install it.
Thanks
Follow the instructions given here to add an installer to your Service application. Pay particular attention to step 5, where you set the StartType property.
To start the service after installation, see Automatically start a Windows Service on install
Try following way,
private void serviceInstaller_AfterInstall(object sender, InstallEventArgs e)
{
var service = new ServiceController(serviceInstaller.ServiceName);
if (service.Status != ServiceControllerStatus.Running)
{
service.Start();
}
}

Categories

Resources