I am new to .NET and seeking help for the Windows Service Updates Notifications.
I have a use case that is somewhat similar to "https://stackoverflow.com/questions/41232170/c-sharp-show-notification-prompting-a-update".
The application is developed in C#.NET and is deployed and running as Windows Service.
However, the application is not using any MSI installer to install it. I am using a batch script that configures the Windows Service application.
Now, I want to show the notifications about the updates about the Windows Service to the user, when the system gets restarted.
I came across about the usage of WCF or by using the Task Scheduler, but not sure which one would be the better solution.
Please advice.
Ok, there are (were, because MS disabled the first one that I'm going to explain) two ways to notify your user about updates from a service.
First, the bad, ugly (and non-working in recent versions) way: interactive services.
You can configure a service as interactive, if you add the SERVICE_INTERACTIVE_PROCESS flag the service will be able to create a GUI that will be attached to Display_0. This presents a ton of problems (trying to show a GUI when there's no user session, if you have two sessions open only the first one will show the GUI and so on) but it's a cheap dirty way to show data to the user. Avoid it.
Second, the right way: a standalone GUI program.
In this case you create a secondary program that will show the data to the user, you can start it with the user session or let the user decide if he wants to receive info by opening manually this application. This program needs to receive the updates from the service in some way, which is better is up to you but I would use UDP for this, in this way your service doesn't needs to care if any GUI app is connected or not, you broadcast an UDP message and everyone listening will receive it, you don't need to mantain a server that handles connections, you don't need to have an storage in order to maintain the event data and it will support any number of instances of the GUI (if more than one user has started a session in the machine all of them will get notified).
But as I said, that would be my preference, you can do it as fancy as you want, you can use Pipes, use a file that contains the event and use a FileSystemWatcher to get notified when changes happen in it, you can even host an ASP .net web app which implements a SignalR hub and then you can create your GUI in html. It's up to you decide which mechanism is the best for your scenario.
Related
I have a question about how best to check if a service is still running.
First a bit of clarification. The service I have is a C# application which can either be run from the command line or can be run as a Windows Service. The function of the service is to check for changes to a remote 3rd party data source and process those changes before adding them to our own local data store.
I want to be able to identify when the service has stopped functioning for whatever reason, and notify somebody when this happens as automatically as possible. This needs to happen regardless of whether the service is being run as a Windows Service or from the command line.
I have already considered monitoring the local data store for changes and notifying when changes haven't happened for a set amount of time, however this has proven to be a little too inconsistent, because the frequency of changes to the 3rd party data source is variable, which means that a prolonged lack of changes doesn't necessarily indicate that the service has stopped working, it could just be that there are no changes!
Are there any suggestions about how I might go about monitoring this? Anyone got any experience working with something similar?
Thanks, M
Edit 1
Just to give a rough idea of how the service works: The 3rd party service raises events when new/updated data is available so my service sits and waits for these events to be raised and processes the data returned in the raised event. Therefore this is why it's tricky to identify when there's "no changes" rather than "service crashed".
Edit 2
I think I need to be a little clearer: The main reason for this monitoring is to notify a user about a potential issue either with the service or with the connection to the 3rd party service. The service itself is single threaded and has proper exception handling and logging. Chances are this service is going to be run on a server somewhere so if there are any problems with the service and it stops updating our local data store for whatever reason the service needs to notify someone.
you might want to consider something like a 'heartbeat':
Heartbeat activity for Windows Service
But your main consideration should be working out why your service should be able to stop/hang? All exceptions need to be caught, and at the very worst case, reset your service to its start state after a short wait to prevent CPU maxing.
Windows itself has a variety of methods to help also:
Start > Run > Services.msc > Right Click Service > Properties > Recovery Options
If you design your application to properly use exceptions and handle them appropriately, you shouldn't ever have a problem with your service 'hanging for some reason'.
Additional:
Is there no way for you do determine the difference between "no work required" and a hang?
you can use ServiceController class in .net to monitor services.
I faced the same problem in one of my projects.
I used the below approach to monitor the my service.
First thing, i logged all the informations,errors from my service to event viewer in a standard format like this
custom-eventid|datetime|message
Then i created one more notification service which will listen to the
event viewer for the particular events,reads the message from the
event entry
if the event entry falls in the event viewer it will send mail
notification through smtp
if you are not provided with the smpt then go for windows application
which listen to the events and shows message using baloon or message
box
The solution that worked for this project was to use a heartbeat like implementation to allow the service to notify me of it's availability.
Because our application uses WebAPI I was able to set up an endpoint which the service "pings" every [x] seconds.
A separate process has been added which checks the date and time of the last notification from the service and if that doesn't fall within a set threshold I notify the user that the service is unavailable.
I looked at using the ServiceController but that was not going to be an ideal solution because of the possibility that the functionality added to the service could be run as a Windows console application instead of a Windows Service.
How can I load a 'login form' in OnStart event of windows Service?! I know windows service is incompatible with UI. but I need to do this without using windows startup..
Is it possible? and how?
Thanks a lot.
How can I load a 'login form' in OnStart event of windows Service?
You cannot do this, because Windows services cannot display a user interface.
I know windows service is incompatible with UI.
Oh. You already knew that. Good.
but I need to do this without using windows startup..
This does not change the fact that it is not supported and will not work.
Is it possible? and how?
No, because:
windows service is incompatible with UI.
So what do I do!?!
The real answer here is that your design is wrong.
If you need someone to log in to your application, you should not be creating a service.
Just make a standard Windows application (e.g., using Windows Forms or WPF) and set it to start automatically when any user logs on to the computer. This can be accomplished easily by adding a shortcut to it to the All Users "Startup" folder.
Then, when your app runs, you can display whatever UI you need to, without the limitations of a service.
If you need to combine UI interaction with a service, you ought to write two programs - the service, which exposes some kind of API, and a client program that interacts with that API (using whatever IPC mechanism you want to choose)
Just remember that multiple users can log onto the same machine, so you ought to write everything to cope with multiple instances of the client program running at the same time.
Im working on application for Windows Server 2008 R2 (.NET 3.5.1) that would work even after cold reboot, without requring someone to log on any account on the server.
Few words about application itself, it is written in c# application for registering employees work time at the company. Users (employees), have thier cards which are beeing scanned by barcode scanner, each scan means either "work started" or "work stopped", everything is serlialized into xml file which is later on modified and put into .csv but that doesn't matter.
Barcode scanner is working as a keyboard, so all codes are beeing "typed" like from a keyborad, to the PC. I made application read the keys despite the fact that console application is not in focus, or not visible at all.
What i need to do is to make that application work even after cold reboot, it has to be fully automatic.
So far i figured out 2 approaches to do it, one is to create a service which would keep another process alive (if its not working, just turn it on), i didin't have much luck with this one, i have already created service that launches another process for me, but the process is working differently, if i would run it myself, there is no communication with the process so i cannot even tell if its the right one.
Another one is to just put my app into registery /microsoft/windows/current version/run, and enable autologon for user with limited prividges. This actually could work but it is not perfect solution, because after all we do not want to have user logged in on server in company 24/7 right?
I know that most of you are way more experienced in programming than i am, so i would appriciate any solutions how to solve my problem
Lichoniespi
Your options depend on physical security of the system (whether passers-by can do much to it apart from scanning a barcode), but let us assume that it is an easily accessible desktop. In that case, you probably do not want a logged in user.
Use the service approach. You do NOT need a separate process for accessing the keyboard. Create a global hook of type WH_KEYBOARD_LL.
Declare your callback function like this and put it into place with SetWindowsHookEx.
I would use the first approach, create a service, and to comunicate with the running application i would be using a network socket or pipe. For the service be sure that you're using an existing user account (not System) and allow it to interact with the Desktop.
I am writing a service based application, and a UI application within it.
I am using Event Logs to log my error, but some of these errors are critical and user should be aware of.
What I need is to check if The UI application (Windows Application Project) is available, and running... if it's running send the error directly to the UI through a service based application (Windows Service Project).
Now, what to do? There are two step I should take, first check if UI is running, second send info like a class instance or a string or binary data (like using serialize) to the UI and UI receive it.
I think the two applications of yours can interact using the Socket mechanism.
And check this for the "is running" bit:
Checking if my Windows application is running
If you don't mind adding a new dll to your project I suggest to take a look at log4net. There is an appender for remoting, RemotingAppender that fit perfectly your needing. You just need to find some samples on how to implement the "receiver" in your UI app. As an additional benefit, you can use the same library to append in the EventLog, or on a file and so on.
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.