I want to write an app that will, given some network input, simulate mouse movements, clicks, and keyboard input. How and Why i want to do that is a different discussion :-) What I'd like to hear from SO is what would be the preferable model for an app/service like this?
Should I make a windows service that
sits in the background running as
system?
or should I make a tray app that
sits in the tray listening and
manipulating the user's input?
I haven't started working on it, so some of the things I'd imagine would trip me up would have to do with the service not having an interactive session, and/or permissions.
Anything I should anticipate or keep in mind?
If you intend to run your code on Vista and Windows 7, a Windows service isn't going to be enough because they can't interact with user desktops anymore. If you're going to be manipulating user input, you'll need a program running in the user's session.
One alternative is to write a service for monitoring the network events, start the client when a user logs in, and use IPC to communicate between the two.
EDIT: NetworkService should suffice for service privileges.
As Aaron suggested, have a Windows service monitoring the network.
As for the IPC to the process in the user session, you can use WCF, and a named pipe is probably the best transport, but you need to design it the right way round in order to get across the session boundary. Make the Service process the WCF service, with a duplex contract: the user session process calls the service to register and then events are passed back to the user session process on the callback contract. See this question for an explanation of the issues.
Aaron gave all the arguments why you can't do without the tray app, but why add the complexity of a service communicating with the app through IPC ?
A service is useful when you need to have code running even when no user is logged in. This isn't the case here, right ?
Unless you have to manipulate the input of multiple users logged in at the same time, I would go with only the tray app doing both tasks of monitoring network events and manipulating user input, it's way simpler to me.
Related
Services can be marked as "not stoppable":
In C/C++ by specifying SERVICE_ACCEPT_STOP flag when calling SetServiceStatus (see SERVICE_STATUS for details).
If .NET, by set ServiceBase.CanStop to false.
However, is this good practice? It means that even a user with administrator privileges cannot stop such a service in a clean manner. (It would still be possible to kill it, but this would prevent proper cleanup. And if there are other services running in the same process, they would be killed as well.)
In my specific case, I have a service which controls a scientific instrument. It has been suggested to make the service not stoppable while it is acquiring data from the instrument in order to prevent losing the data being acquired. I should add that:
We grant non-administrator users the right to start/stop the service
We have program that provides a UI to start/stop this service. This program will issue a warning if the user tries to stop the service during acquisition. However, it is of course also possible to stop is with SC.EXE or the "Services" snap-in. In this case, there is no warning.
Does Microsoft (or anyone else) provide guidance?
My own stance so far is that marking a service not stoppable is a drastic measure that should be used sparingly. Acceptable uses would be:
For brief periods of time, to protect critical operations that should not be interrupted
For services that are critical for the operation or security of the OS
My example would not fall under those criteria, so should be stoppable
I have a Windows Service that I want to monitor. Let's say this service may suddenly lose it internet connection, without the host system knowing.
I need a reliable online monitoring service that allows me to send a "I'm still alive" signal to, having them send me a mail, if my service has not "reported in" within the last X minutes.
All services I can find are regular monitoring services that connects to my website/service to see if they're running. I'm looking for a provider that allows me to do the opposite.
This seems like an insanely simple service, and I cannot understand how I cannot find anything usable anywhere? :\
you need newrelic.
Either use the client, or build your own custom instrumentation. You can do probably anything you like.
Update :
Another option is scoutapp.
Probably same features but with plugins.
Fiveruns was another option but I guess the are not in business anymore.
I can understand these features sound too much for your simpler scenario, why not build something for your own? All you need is a service that accepts a post and send an email to you.
I'm currently designing an application for iOS (using MonoTouch) that will have a server component running on Windows Azure. The application will essentially be a chat type application where users will generate messages within their clients and send them to the server, which will then need to forward those messages out (as quickly as practicable) to other clients that the user might be sending the messages to.
My question is - is there a recommended practice for architecting an application like this, where clients need to receive 'push' messages from the server?
I've considered a few options but would appreciate feedback.
The first option is to use Apple's Push Notifications service (APNs). I have two concerns about this - first, the clients only need to receive the messages when they're online (APNs sends messages through when the app is closed too, which I don't need or want); and second, there is a possibility that there will be a high volume of messages, which I know Apple would probably get unhappy about (perfectly fairly).
A second option I considered is using a web service (WCF-based) and having the client call this service every (say) 2-3 seconds, which is the maximum delay we could tolerate. This would seem to involve a great deal of potentially unnecessary network traffic, though ("have you got anything for me?", "no", repeated ad nauseum).
A third option is to maintain a persistent web service connection between the client and the server. When the client app starts it would call a web service method on a background thread. The server would hold the connection open (by not returning anything), and if any messages came through it would immediately return them. This connection might time out after, say, 2 minutes at which point it would be re-established. This seems to do what I want, but again, I'm concerned that there'd be a lot of connections open to the server at any moment, which could require server resources unnecessarily.
A fourth option is to use a persistent connection over TCP (or UDP, although from what I've found, Windows Azure doesn't support this). This seems to be a good option, but again, might be overkill in terms of server usage - there could potentially be hundreds or even thousands of clients connected at any moment.
A fifth option is to somehow have the server push messages directly to the client, perhaps by having the client run a mini web server or similar. However, as the app will be running on 3G and WiFi networks (beyond my control) I don't expect incoming ports will be open for this sort of thing.
If anyone has any other suggestions, or thinks one of the above options would be a good idea (or is a standard way of approaching this sort of problem) I'd be very interested to hear about it.
Thanks in advance,
John
You had a look at Pubnub http://www.pubnub.com/ ?
I'm using the UPS service to monitor the state of my UPS from an application -- the key at HKLM\SYSTEM\CCS\Services\UPS\Status has all the information you can get from the Power control panel. BUT -- I'd like to be able to tell the UPS to shut down from my app as well. I know that the service can tell the UPS to shut down -- for instance, after running a set number of minutes on battery -- and I'm wondering if there's some kind of command I can send to the service to initiate a shutdown manually.
I'm having trouble searching for this information -- people tend to misspell "Uninterruptible" (hrm, Firefox red-lined that but doesn't have an alternative) and "UPS" just gets hits for the shipping service. Maybe I can do something through System.ServiceController, or WMI?
CLARIFICATION: Yes, I am talking about powering down the physical UPS device. I know how to stop the service. I figured it would be a common problem -- I want my UPS to turn off with the PC. I had an idea I'm going to try, based on this page. You see, APC (and everybody else) has to supply a DLL for the UPS service to call, and since the function calls are well documented, there's no reason I shouldn't be able to P/Invoke them. I'll re-edit this once I know whether or not it worked.
Update: I tried invoking UPSInit, then UPSTurnOff, and nothing happens. I'll tinker with it some more, but the direct call to apcups.dll might be a dead end.
Check my comments to Herman, you want to shut the UPS down, not the UPS SERVICE, correct? I mean, you want that thing to shut off, kill the power, etc, right?
If so, you are looking it on a UPS by UPS model. I doubt two of them would work the same.
In your searches, instead of UPS, try "APC", or "battery". I think a lot of the code is what runs on laptops to deal with being on battery, etc...
Some place hidden in some dusty old files I have protocol information for APC UPS's, and the commands they respond to, and what they send to the PC etc. But this was WAY back in the day when we used to connect our UPS's to our computers with SERIAL cables... You could actually talk to a UPS with Qmodem or Hyperterm...
Learned it from talking to the guys at APC. They are very nice, and helpful. Now-a-days, I think you just post a URL coming from your Powerchute software, and it will talk directly to the UPS, and carry out your commands.
OK, I have the answer (tested!), but it's not pretty. My APC UPS communicates using the APC "Smart" protocol (more here). What you need in my case is a "soft shutdown", "S" command. But first you need to make sure it's in "Smart" mode ("Y"). Now, if you want to let the Windows UPS service monitor state, the service will have an iron grip on the COM port. So you can either a) let the Windows service turn the UPS off, or b) kill the service and turn the UPS off yourself.
The UPS itself has a "grace period" after it gets the "S" command, giving you time to shut down your OS. This means that to do (a) above, you have to:
Kill utility (mains) power
Wait for the Windows UPS Service timeout (default and minimum 2 minutes)
Wait for Windows to shut down -- right near the end, it will send the "S" command
Wait for the UPS grace period, after which it will actually turn itself off
I think we're going to opt for (a), just because (b) involves extra work killing the service and implementing the serial comms.
Please, tell in what language are you trying to do that... if you're using .NET you can do that with ServiceController class (read the docs).
For controlling services in Win32 API using C/C++, Service Functions (Windows).
For example to stop a service you can use ControlService function as follows (this is a quick and dirty example):
OpenService (hServMgr, TEXT("\\UPS_SERVICE_0"), SC_MANAGER_ALL_ACCESS);
SERVICE_STATUS stat;
ControlService (hUpsService, SERVICE_CONTROL_STOP, &stat)
Note that you need to provide a Service Manager handle in hServMgr and the \\UPS_SERVICE_0 name is the name that must match with your desired UPS service (either the Windows built-in or another).
Remember that to stop a service you need the proper security rights. This is not a problem with an Adminstration account, but keep in mind what happens when logging with a non-admin account.
Hope that helps.
About shutting down the physical UPS device, I remember back in WIn98 days I was able to poweroff the device talking with the UPS through the COM port, altough I don't remember the brand or how the programming interface was.
I understand that Window's Services have no desktop, and can't access any of the user's desktops directly (indeed, they can run when there is no desktop loaded). Why is it though that launching a form in a Window's Service causes an error?
A service should run without any user interaction, so there is no need for a form. If a service has to wait around for user feedback then it probably isn't going to be doing what it is supposed to.
You have to understand three related concepts: sessions, windows stations and desktops. But because there's a one-to-one relationships between sessions and stations, we can broadly ignore stations for this discussion. A session contains a station (winSta0 being the only interactive station) and stations contain one or more desktops.
Now session architecture differs according to Windows version. For NT <= 5 (XP/2003 and everything before them) services execute in session 0 along with the interactive user's apps. This is why you can configure services to interact with the desktop in these Windows NT versions - they are in the same session. For NT >= 6 (Vista, Server 2008 going forwards), services exists in session 0 but the interactive desktop is in another session. This is what's known as "service hardening", and is basically a security fix.
So since session 0 apps cannot get at the interactive console, it makes no sense for them to attempt to display a user interface of any kind.
Just to make this more confusing, Vista has a temporary kludge to cater for this situation: if an app in session 0 tries to create a dialog, Windows will trap this and present a warning to the user so they switch to a (I presume temporary) desktop where they can interact with the dialog. However this measure is explicitly temporary and you cannot rely upon it being in future Windows releases. I've seen this working in native code, but I suspect you are in managed code and the runtime is being smart enough to catch your behaviour and deliver a metaphorical slap to the hindquarters :-).
Ummm... what and whose desktop is that form going to appear on, exactly? A 'desktop' is an operating system concept: each window handle is owned by a specific desktop within a window station belonging to a single (interactive) user. The process within which the service is executing isn't going to find the user's visible desktop in its window station. For a rather dry reference, look at MSDN.
Actually, it's even nastier. You might be able to configure permissions for the service to be able to create a desktop -- but then nobody will see it! Alternatively, you could grant the process the rights to switch desktops, and confuse the heck out of the user!
There's a setting you must enable in order to allow your Windows Service to access certain folders directly (like desktop) or show forms (including MessageBox pop-ups): "Allow service to interact with desktop"
To see this, right click on My Computer => Manage => Services and Applications => Services. Double-click on a service to access its properties. On the "Log On" tab there is a checkbox for this setting.
Here is an article for how to set it programmatically in C#
[Edit] As Stephen Martin points out in the comments: this is only valid advice for pre-Vista versions of Windows.
Because if nobody is going to see the Form, nobody is going to dismiss it - running a modal dialog is a recipe for a hang - so you want it to complain loudly when this happens rather than sit there quietly until you kill the process (or look at a stack trace to determine what'd going on). (The other obvious problem is, who is going to pick the DialogResult if there is more than one possibility?) You want to know when this is happening. (Assert dialogs that dont throw if they cant show anything are a fun way of making people mad.).
In other words, because you want to know when things are confused enough in your code that a dialog is being shown within a service context.
(I'm assuming you're using Windows Forms on .NET, eve though you didnt tag it as such)
(If you have correctly configured things such that the service is allowed to interact with the desktop, you won't get an Exception)
When a Windows Service is started it is assigned to a Window Station and Desktop according to well documented, though somewhat obscure rules. As mentioned elsewhere it is not assigned to the interactive desktop (unless it is set to interact with the desktop on a pre-Vista OS) but it definitely runs in a desktop.
It is a common misconception that services cannot use UI elements. In fact many services (such as SQL Server) have in the past used hidden windows and windows messages for thread synchronization and work distribution purposes. There is no reason that a Form cannot be shown in a service. If you are getting an error it is due to something you are doing with the form or some component that is on the form. The most likely issues have to do with whether or not you need an STA thread for your form or are you creating a message pump for your form or something similar.
While you certainly can use a form in a Windows Service you almost certainly shouldn't. There will be threading issues, cross apartment call issues, possible blocking UI issues, etc. There are a very few situations where using a window in a service is a good choice but there is a better way, with no UI, in 99.99% of all cases.
Because at the time when the operating system needs to paint the window there is nothing to draw the form on.