I have implemented a background service that sends some data to server.
But the service is only triggered after the trigger is fired.
I want the service to fire immediately as and when its registered.
I have tried
DeviceTrigger
LocationTrigger
SystemTrigger(Internet available/Timezone-changed)
MaintenanceTrigger
TimeTrigger
but they all are fired when their conditions are met as documented. Does any one have any idea how to get this work, btw I'm on windows phone 8.1 and C++.
PS. I just want my service to get triggered as it is registered.
AFAIK you can’t do that directly. Microsoft is very strict about what background tasks can and cannot do because battery life depends on it.
There’s a workaround.
Move your server-sending functionality from your background service into a separate DLL. Call that DLL from both background service process, and the GUI process. If you need to, in that DLL you can guard shared resources with a named mutex or use any other IPC mechanism that works across processes.
Related
I have a GUI application that is used to configure a windows service and I want to start, stop or restart this service from thing GUI application.
One of the problems is that this service can run in two modes: windows service or manually from command line (so you have a console).
Now, I am looking for a way to communicate this, a way that would work in both cases.
It may be helpfull to specify that the service process already has and even handler that is dealing with:
CTRL_C_EVENT
CTRL_CLOSE_EVENT
CTRL_BREAK_EVENT
CTRL_LOGOFF_EVENT
CTRL_SHUTDOWN_EVENT
It would be quite easy to extend the handler if I knew what event will be triggered by the service restart option. Still, I should be able to trigger the same event from my GUI application so I will be able to tell the "server" to restart itself even if it is running in background.
The best is would be if I could do this without having to detect in which mode the server application is running.
There are Service Trigger Events that your service can listen for, and then your GUI can send an event. In particular, you want to register for an SERVICE_TRIGGER_TYPE_CUSTOM trigger, which causes your service to listen for an ETW event; your GUI code would then write the ETW event to trigger the event.
There is no service restart action. All you would do is stop the service normally, then start the service normally afterwards. That is all the SCM restart does internally, it is just exposed as a single operation in the SCM UI instead of as two separate options.
First off, I know some proper ways of making a truly interactive Windows Service.
The situation is, I do have a tool that does not interact with the user as such. However, it does display non-blocking notifications both via popup windows and via the Windows Notification Area (aka System Tray). It also writes a logfile of the notifications it displays.
This tool is normally spawned by a main user application and as long as the main application is a normal application, these notifications do work as intended.
When this tool is spawned by a Windows Service, no notifications are displayed, naturally. (The Desktop Session for the service isn't visible.) But this would be OK, we have the logfile and these notifications are just - notifications, nothing the user absolutely must see under all circumstances.
The question now becomes: Is a process running in the context of a Service (the Service itself or any process it starts) "allowed" to make Windows API calls that display a visible GUI?
Will most Windows API calls (e.g. creating and showing a window, using Shell_NotifyIcon, etc.) behave the same in the invisible session of the service?
Or would I have to make sure throughout the source code, that no GUI displaying/modifying stuff is called in the context of the service?
And yes, calling ::MessageBox is a bad idea because it will block. But I can handle these calls.
And yes, this could be designed better, but it's what I have at the moment and it would be nice if I hadn't to rip the whole tool apart to make sure no GUI related code is run in the service.
GUI elements from a Windows Service are shown on Session 0. On Windows XP & 2003, users were allowed to log in to Session 0 and interact normally with the windows created by a service, but Microsoft put a knife in the heart of interactive services in Vista (and beyond) by isolating Session 0.
So, to answer your specific questions:
Is a process running in the context of a Service (the Service itself
or any process it starts) "allowed" to make Windows API calls that
display a visible GUI?
Will most Windows API calls (e.g. creating and showing a window, using Shell_NotifyIcon, etc.) behave the same in the invisible session
of the service?
Yes, GUI calls are allowed and should succeed as normal. The only notable exceptions that I know of are those related to tray icons because the process providing the task bar (explorer.exe) is not running in the isolated Session 0.
Or would I have to make sure throughout the source code, that no GUI displaying/modifying stuff is called in the context of the service?
That should not be necessary, though you should proceed cautiously with any GUI interaction from your service. Test thoroughly!
I would like to provide some info wrt. Raymonds Chen's comment to the other answer
You should avoid presenting UI in a service because you may trigger
the UI Detection Service which will switch the user to your service UI
temporarily. – Raymond Chen
I find these good articles:
What is Interactive Services Detection and Why is it Blinking at Me?
Inside Session 0 Isolation and the UI Detection Service, Part1, Part2
Where one can find explanation on what the UI detection service (UI0Detect) is and does and how it's supposed to work.
Interactive Services Detection (the blinking button on the taskbar) is
a mitigation for legacy applications that detects if a service is
trying to interact with the desktop. This is handled by the
Interactive Services Detection (UI0Detect) service.
However, one must note that this only can work if the service that is trying to view a GUI has the flag "Allow service to interact with desktop" set, because only then the service process will be running on WinSta0of Session0 even allowing it to show anything at all.
Alex Ionescu mentions this:
If UI0Detect.exe ...
the SCM has started it at the request of the Window Hook DLL. The
service will proceed ...
The service first does some
validation to make sure it’s running on the correct WinSta0\Default
windowstation and desktop and then notifies the SCM of success or
failure.
So, to come back to Raymond's comment: As far as I can see, as long as a service doesn't tick the type= interact option (see sc.exe), and normally you don't tick this, the UI0Detect service doesn't do anything and there shouldn't be any "danger" of triggering it.
Note: The information above is based on my limited research and tests on only a single Windows 7 PC.
I have an app which needs almost no user interaction, but requires Geofences. Can I run this entirely within a background service?
There will be an Activity when the service is first run. This Activity will start a service and register a BroadcastReceiver for BOOT_COMPLETED, so the service will start at boot. It's unlikely that this Activity will ever be run again.
The service will set an Alarm to go off periodically, which will cause an IntentService to download a list of locations from the network. This IntentService will then set up Geofences around those locations, and create PendingIntents which will fire when the locations are approached. In turn, those PendingIntents will cause another IntentService to take some action.
All this needs to happen in the background, with no user interaction apart from starting the Activity for the first time after installation. Hence, the Activity will not interact with LocationClient or any location services.
I've actually got this set up with proximityAlerts, but wish to move to the new Geofencing API for battery life reasons. However, I have heard that there can be a few problems with using LocationClient from within a service. Specifically, what I've heard (sorry, no references, just hearsay claims):
location client relies on ui availability for error handling
when called from background thread, LocationClient.connect() assumes that it is called from main ui thread (or other thread with event looper), so connection callback is never called, if we call this method from service running in background thread
When I've investigated, I can't see any reason why this would be the case, or why it would stop my doing what I want. I was hoping it would be almost a drop-in replacement for proximityAlerts...
Can anyone shed some light on things here?
The best thing would be to just try it out, right? Your strategy seems sound.
when called from background thread, LocationClient.connect() assumes that it is called from main ui thread (or other thread with event looper), so connection callback is never called, if we call this method from service running in background thread.
I know this to be not true. I have a Service that is started from an Activity, and the connection callback is called.
I dont know about proximity alerts; but I cant seem to find an API to list my GeoFences. I am worried that my database (sqlite) and the actual fences might get out of sync. That is a design flaw in my opinion.
The reason LocationClient needs UI, is that the device may not have Google Play Services installed. Google has deviced a cunning and complex mechanism that allows your app to prompt the user to download it. The whole thing is horrible and awful in my opinion. Its all "what-if what-if" programming.
(They rushed a lot of stuff out the door for google IO 2013. Not all of it are well documented, and some of it seems a bit "rough around the edges").
I need to track to a log when a service or application in Windows is started, stopped, and whether it exits successfully or with an error code.
I understand that many services do not log their own start and stop times, or if they exit correctly, so it seems the way to go would have to be inserting a hook into the API that will catch when services/applications request a process space and relinquish it.
My question is what function do I need to hook in order to accomplish this, and is it even possible? I need it to work on Windows XP and 7, both 64-bit.
I think your best bet is to use a device driver. See PsSetCreateProcessNotifyRoutine.
Windows Vista has NotifyServiceStatusChange(), but only for single services. On earlier versions, it's not possible other than polling for changes or watching the event log.
If you're looking for a user-space solution, EnumProcesses() will return a current list. But it won't signal you with changes, you'd have to continually poll it and act on the differences.
If you're watching for a specific application or set of applications, consider assigning them to Job Objects, which are all about allowing you to place limits on processes and manage them externally. I think you could even associate Explorer with a job object, then all tasks launched by the user would be associated with your job object automatically. Something to look into, perhaps.
I created a service in Visual C++. Installed it using instsrv.exe and srvany.exe.
When I check at the Services applet in Control Panel, the service is registered. But when I want to start it, this message appears:
the service on Local Computer started and then stopped. Some service stop automatically if they have no work to do, for example the Performance logs and Alert Service.
I just have this code inside my OnStart function:
(void)system("C:\ReleaseExe\Example1Server.exe");
I my code correct? Or is there any other way to code it to make sure that the service can be in running state?
Assuming that exe you are starting up is actually your service, this is the wrong way to do it.
The Windows Service Control Manager (SCM) actually calls into your service's EXE via defined entry points - you need to provide the logic to do what your particular service needs in those entry points, including notifying the SCM of state changes in your service (STOPPED-> RUNNING, RUNNING->STOPPED, and so on).
Read the background info on MSDN, starting here, for clarification of what you must provide. Note that OnStart is specific to implementing Services in managed code, you won't be doing it that way in Visual C++. Perhaps C# would be an easier route?