I have created a message Queue here which is basically on a single thread and sending email one after another from the database. First I thought that since it is a continuous process, it has to be on windows service and it sounded like an ideal solution but not that I talked to my manager, he said that it would be better if it is in the same repository as the entire project and if I put in a while(true) statement. that way while deploying to the production, we do not need to worry about installing any windows service or anything. But what I think here is that if we do it that way then there would be a lot of unwanted pressure on the web server.
I am not sure which way to go. Any suggestions?
I would definitely suggest a windows service for processing the email queue in the background. Here are some points you can suggest to your manager:
The service could be kept in the same repository as another project.
Installing and upgrading services is very easy. Use installutil and add a batch file to your project for installing/uninstalling. Upgrading is a matter of stopping the service, updating the service .exe, and starting the service again.
All of this could technically be automated as well as part of your deployment process.
I'd go with a separate Windows service. With this service being party of your application, its life time is dependant on the life time of the application pool process (depending on the version of the IIS you are using, of course), and this way whenever youll choose to change the application pool settings, you will have to remember ur message job is also dependant on it, and if you set up any recycle settings for the app pool, you might have hard time uynderstanding why your job suddenly stop working or anything like that.
You can also go the route of simply writing a command line application and then wrapping it with something like Service+ to make it behave like a service. You also get other features like being able to run it like a command line application if you like (whenever you want to run it) or having it launch/execute from some other application as needed. You can build in a variety of behaviors as well... continuous mode, perhaps process 1 (or 100 or whatever) at a time then exit (and let Service+ restart it), or whatever else you may need.
Related
I have a Windows Forms Application which runs on a server. I need this Application to always start automatically. Even if the Server just gets restartet and nobody logs into it the Application should run.
So the solutions with Registry don´t work here. I than read into Windows Services but it seems like I can´t start a WinForm Application with it.
Does anyone have an idea how I can achieve this automatic Start on Server startup?
The way we do things like that is that we create a Windows Service which runs without the need to have anyone logged in, and then if there is a need we have a separate GUI application (WinForms in your case) which interacts with the service, when needed.
The communication between the GUI application and the Windows Service is usually done by means of named pipes, but if you can get away with something simpler, like the GUI application saving a configuration file for the service to pick up, you might make it easier for you.
So I created a Windows Service using C# and created an installer in Visual Studio for it. It's set up to run manually as I don't want it running all the time. I then have another application (C# WPF) that should have an option to turn the service on and off (the service itself creates a web service that in turn communicates back to my WPF application). This works fine in Windows XP, but testing it on a Windows 7 machine, it won't start. Surprisingly it does throw an exception and crash, it just does nothing. I believe this is a permissions problem. If I go to the services control panel using the same Windows 7 account, I'm not able to start or stop the service either.
So my question is, is there a way to set my service so that regular user accounts can start and stop it? And is there a way to set my installer to do this automatically.
I don't want my WPF application to have run as administrator!
Whilst I believe that it is possible to secure a service so that regular users can start and stop it, I do not recommend doing so. This will create a lot of complication and is a potential cause for confusion. I always prefer to keep things simple, especially when it comes to installation and security.
So, if we can't let the user start and stop the service we probably need to let the service run all the time. Since you don't want the service to be active all the time I suggest you give the service its own internal Running flag. When this is set true, the service is active and does busy things, otherwise the service remains idle. You can use your preferred IPC mechanism (sockets, named pipes, WCF etc.) to allow the user to toggle this switch.
Windows 8 has a feature to allow services to start on demand, basically in response to some kind of trigger. But for Windows 7, your only real option is to set it to start automatically on startup. You could set it to start delayed, so that its not adding to the time it takes windows to start.
Regular users cannot start and stop services.
EDIT: Reading the link in the comment above it sounds to me as that is a blanket ability for users to start and stop services. I think the question here is about how to do this for a particular service.
Also, while it may be possible to set the service to run as that particular user, it really means it only works for that particular user and other users on the work station would not be able to use the application as they'd not be able to start or stop the service, assuming that the service running as a user implies that the user may control it, which may not be the case.
Also in reading the comments and other answer, I'm left to wonder if the service can be used by any user which can run the application. That is, if user A logs on to the work station and starts this app (and thus the service), locks it and walks away, what happens when use B logs on and tries to run the same service? Can the service support multiple users at the same time, or will funny things begin to happen if the service is utlized by the application running multiple times.
This really sounds like what is desired is for a background to be started when the application starts. This thread (or threads) would do the work of the service, and by their nature would end when the application ends. Of course more detail in the question would help give a better answer.
Of course if it is appropriate as a service, I see no reason not to have a service with a worker thread that sleeps, and another timer thread that acts as a producer that checks if there's work to do.
I have a requirement that a Windows Forms C# .NET 2.0 program running in user-space (not a service) must always be running. As I'm not infallible and make coding mistakes, I wanted to know of any extra safeguards I could use to ensure this requirement is met. The things I've been thinking of are TaskScheduler to check it every 5 minutes, A stub watcher or a secondary process. Are these good / bad ideas?
Thanks,
Richard
EDIT: The reason I didn't use a service (the obvious and sensible answer!) was the program runs in a kiosk type environment and has has a heavy GUI component. The service option didn't work well across Windows 2000 - W7.
EDIT: The second reason not to use a service was the app needs internet access and on some of our customer sites, proxies are set up to only allow specific users (not the local system account) so it would be tricky to ensure access if multiple users log onto the machine.
Task scheduler is a cheap solution for this which does work. I use this to keep our Perforce Proxy server running (had some issues with the service), and so far there's been no problems - though now I've said that the server's probably exploded!
However, the most complete solution is a Windows service which invokes your app. You can make that service catch error return codes from the app, restart it on failure and notify you by email, which may help you diagnose and fix those issues. I think the Task Scheduler does something similar but it won't be able to provide as much insight into your application as a custom service.
If you're unsure of how to do that, then something like this should work:
http://www.codeproject.com/KB/install/csharpsvclesson1.aspx
There are three approaches that you can take:
Heartbeat Message.
A heartbeat is useful in a distributed application and is simply message that is sent (from let say a client to server) to confirm that it is still healthy/running.
Manager Process
A stub program, implemented as either a user process or a service. It launches the main application, monitors any unhandled exceptions, reports errors, and restarts on failure.
An exception guard on the entry point.
A try-catch-all in the application entry point.
I would recommend either of the first two options; the third option, the try-catch-all, is a particular nasty hack for the lazy and inexperienced programmer (IMHO).
I have successfully used both heartbeat and manager process in a large distributed application.
UPDATE
As for ready-to-go™ restart managers, take a look at the Windows API Codepack as discussed in Emmanuel Istace blog post (http://istacee.wordpress.com/2013/09/21/automatic-recovery-restart-in-net-application/).
You can install the package from https://www.nuget.org/packages/WindowsAPICodePack-Core/
I have built one windows service that sends out email after every 30 minutes in C#. The Service start mode is set to Automatic. But still windows doesn't start automatic. I need to manually start by going to Services.msc and right clicking the service and select start
When the StartMode is set to automatic, that just means that it will start up when Windows boots up.
You can start the service yourself in a custom action in your installer. I assume you have an Installer class already and that it is already a custom action for your setup project since the service is installing, but not starting.
Override the OnAfterInstall method in the Installer class you have and you can start the service like this:
protected override void OnAfterInstall(IDictionary savedState) {
base.OnAfterInstall(savedState);
ServiceController sc = new ServiceController(“MyServiceName”);
sc.Start();
}
However, a scheduled task is not a bad way to go.
Why put yourself through all the overhead and suffering of troubleshooting and maintaining a windows service for a time based/polling application? The windows OS has built in support for this. Just create a simple console application. Run it as a scheduled task.
You should already have unit tests and decoupling to make the code unit-testable. If you don't your troubleshooting is overly difficult. Once you have your code in this unit-testable format flipping to a console app is a no brainer.
I knew a guy who made everything a windows service and labeled it SOA. Piling up windows services for polling/time based mechanisms isn't SOA. Its so sloppy compared to console applications and so much more difficult to maintain I can't even begin to express how bad an idea it is. I had to deal with about ~20-30 of these win services and once they were converted to n-tier and a console app suddenly the stability of the application went through the roof and my life got 10x easier. So please, do yourself a favor and listen to somebody who has been through months and many iterations of these types of app. Run it as a scheduled task in a console app.
Auto-starting services are subject to problems with service initialization order. You have plenty of dependencies, the TCP/IP stack better be in working order before you try to send an email, for example. Look in the Windows event log for an exception message that prevented OnStart() from getting the service started.
This can be configured for a service, check out the Dependencies tab for the Print Spooler service for example. This is however difficult to deal with, hard to figure out exactly which services need to be running and hard to write the registry entries that configure the dependencies.
Punt the problem: don't send an email message right away. Wait a while, 30 minutes for example.
You install it with installutil? You're right, it doesn't start the service, even if it's set to automatic. If I were you, I'd provide a batch file which calls installutil and then also runs 'net start whatever'. Or if you're using other kinds of installation, those should provide this ability too.
What are some best practices for being able to deploy a Windows service that will have to be updated?
I have a Windows service that I will be deploying but might require some debugging and new versions during the beta process. What is the best way to handle that? Ideally, I'd like to find a ClickOnce-style deployment solution for Windows services but my understanding is that this does not exist. What is the closest I can get to ClickOnce for a Windows service?
A simple solution that I use is to merely stop the service and x-copy the files from my bin folder into the service folder.
A batch file to stop the service then copy the files should be easy to throw together.
Net stop myService
xcopy \\myServerWithFiles\*.* c:\WhereverTheServiceFilesAre
net start myService
I have a system we use at work here that seems to function pretty well with services. Our deployed system has around 20-30 services at any given time. At work we use a product called TopShelf you can find it here http://topshelf-project.com/
Basically TopShelf handles a lot of the service related stuff. Installing, Uninstalling etc all from the cmd line of the service. One of the very useful features is the ability to run as console for debugging. You build one service, and with a different cmd line start you can run it as a console to see the output of the service. We added one custom feature to this software that lets us configure profiles in advance. Basically our profiles configure a few things like logging, resource locations etc so that we can control all that without having to republish any code. All we do is run a command like
D:\Services\ServiceName.exe Core.Profiles.Debug or
D:\Services\ServiceName.exe Core.Profiles.Production
to get different logging configurations.
Our build script creates install.cmd and uninstall.cmd scripts for each of our services all we do is copy the files to the server and run the script. If we want to see debug output we stop the service and double click the exe and we get a console to read all the output.
One more thing that topshelf has which we don't use because its not necessary is the concept of shelving (there is documentation on this website for this). This allows you to update the service without having to "restart" but you still need to copy the files manually unless you build an automated system for that.
However, my suggestion if you need 100% service availability is to have a redundant system. No matter how you configure your service for updates you cannot avoid hardware failure causing downtime without an automated failover system. If said system was in place my recommended update strategy would be to turn off 1 node, update, test, turn on turn off the other node, update, test and turn the 2nd node back on. You can do this all of course with a simple script. This may be a more complicated system than you need but if you can't take a service offline for a simple restart that takes 5 seconds then you really need some system in place to deal with hardware issues because I can guarantee it will happen eventually.
Since a service is long-running anyway, using ClickOnce style deployment might not be viable - because ClickOnce only updates when you launch the app. A service will typically only be launched when the machine is rebooted.
If you need automatic update of a service then your best bet might be to hand-code something into the service, but I'd forsee problems with almost any solution: most install processes will require some level of user interaction (if only to get around UAC), so I can't imagine this would lead an answer that doesn't involve getting a logged-on user in front of the screen at some point.
One idea that might just work is active-directory deployment (or some similar equivalent). If your service is deployed via a standard MSI-type installer, AD allows you to update the application silently as part of the computer policy. I suspect you'd have to force the server to refresh the AD policy (by rebooting or using gpupdate from the console), but other than that it should be a hands-off deployment.
I would suggest using the "plugin" approach on this, that is, using the Proxy Design Pattern.
While using this pattern, an independant thread may verify over a folder for updates. You will need to use ShadowCopy over your assembly deployment. When your service update-thread encounters a new version of your service, it shall unload the current production assembly and load the new version, without stopping the service itself. Even more! Your service should never notice the difference, if there is no breaking code within your assembly.
I would suggest to create a normal setup project, and add the windows service project output in that setup project.
For more information please refer to http://support.microsoft.com/kb/816169.