Windows GlobalSystemMediaTransportControlsSession Events Not Fired in Service - windows

I'm trying to listen to events dispatched by GlobalSystemMediaTransportControlsSession in a Windows Service (in Rust).
I made a reproduction repository with instructions.
The most important part is this:
session.PlaybackInfoChanged(TypedEventHandler::new(move |_, _| {
tx.send(()).ok();
Ok(())
}))
Here a new event handler is created that listens on every open application that emits SMTC metadata for changes to the playback, i.e. play/pause/stop events.
Once the event is fired, the application terminates (rx receives an event).
This works fine in a "regular" executable (e.g. by running cargo run).
However, once I'm running this as a service (through nssm*), no event is emitted (the log-file is not created/written to).
I couldn't find any documentation by Microsoft related to services and events. Is there a workaround, am I doing something wrong or is this known to not be supported?
(*) I'm using nssm here, but the same happens when I'm running the executable as a service. This however would include unnecessary code for managing the service.
So I'd guess the problem is that the executable doesn't run with the user-account.
Then I'm wondering why I can get the sessions, and even metadata, in the first place and no error is thrown/emitted.

Related

Run background service immediately on registration WindowsPhone 8.1

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.

How to tell a Windows service to restart or reload its configuration?

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.

How to list Windows Services from within a Service

sc query state= all works as expected from the command line.
From within another Service, sc query state= all doesn't print anything to that sub-process' stdout (captured by the parent, of course).
Is there a permission/privilege that the Service needs in order to list/start/stop the other servies?
A little background: I am making a service that periodically restarts some misbehaving services.
Well, for one don't do that, at least not in a blocking manner. In order for your own service to respond to the SCM (Service Control Manager) in order to return its status, the service has to be able to execute its dispatcher code. This means that if you call this program and wait for it to exit you'll wait indefinitely. One way to mitigate this would be to put this into a separate thread so it's not blocking your dispatching and your service will continue to talk to the SCM.
Alternatively (and probably better) you could use the EnumServicesStatusEx function to talk to the SCM and inquire about the statuses of other services yourself. The function itself doesn't mention anything about being blocking, so you'd have to figure out yourself whether it is and then use a thread again to prevent your service from stopping to talk to the SCM.
One last note: if those misbehaving services are yours, you should more likely fix the respective code. I've had a share of legacy code and had one misbehaving service which got its own helper application as "fault action" (can be configured in service configuration as SERVICE_CONFIG_FAILURE_ACTIONS) that would go about and restart the service whenever it crashed. Once I took that code over, figured out the cause and fixed it, the service was stable again and that application isn't really needed anymore.

What Windows API to look into for building a scheduling application?

Why not use the Windows scheduler?
I have several applications that have to run at certain times according to business rules not the typical every weekday at 1pm.
I also need a way for the applications to provide feedback of their progress so that I can have rules that notify me when the applications are running slow or aren't even running anymore.
What Windows API should I be looking into? (like, a time version of the FileWatcher apis)
What's the best way to have the application notify the scheduler of its progress (files, sockets, windows messages, ???)?
For Vista/Win2k8, there's the nice Task Scheduler 2.0 API: http://msdn.microsoft.com/en-us/library/aa384138(VS.85).aspx. Previous version have the Task Scheduler 1.0 API, but I've never used it.
AppControls has a CronJob component that you can use to create scheduled events. This saves your program from having to wake up every minute and check the schedule itself. Instead, just schedule the job and indicate a callback method.
I have used this component for scheduling jobs myself and have been very happy with the way that it works.
I think what you really want is a common framework for your applications that report to something (you or the system messages or tracing or perfmon, event log, whatever) and also to receive via some inter process protocol a way to receive messages and respond.
based on the reporting you can change the scheduling or make changes, etc.
So, there is some monitor app, and then each of your other apps does common reporting.
events I can think of:
- started
- stopped
- error
- normal log messages
- and of course specific things your apps do.
I think there are probably existing classes/framework that do this - you'll have to check around.
If it were me, I would make a service that could talk to all the other apps and perhaps was even an http server. It would be able to route messages to particular apps and start stop those processes and query them.
There are lots of ways to do what you want though. those were just off the top of my head.
Alternatively you might just be able to get these to be services and they handle messages sent to them. Their normal processing does nothing until they are "woken up" with some task command.
You have more questions in one. Normally you should split them. But let's overlook this and try to answer.
To schedule certain events (including running an application): Use TJvScheduledEvents from JVCL. IMHO JVCL is the best Delphi open source library around with extensive number of components, developers & support. TJvScheduledEvents is quite neat, uses threads for event scheduling and also you have in JVCL a detailed editor for your events (it needs a small hack to use it though).
To provide 'feedback' from your applications to a (remote) central point: A very very very good solution (if your requirements permit) is to log the progress of your applications in a table (let's call it LOG) on a Firebird server. In LOG you can have the following fields: COMPUTER, USERNAME, APPNAME, MSG, LOGDATE (etc. etc.). In the After Insert trigger of the LOG table you can fire an event (let's call it NEW_LOG). In your console app you can register the interest for this event and so, your application will be automatically updated with everything which happens in any of your applications, so you can do log analysis, graphs etc. Of course you can do it with IB, but IB costs.
...going on Windows API route you need headers (which probably aren't translated), you'll encounter our dearest Pointers/PChars etc. etc. Of course, building from scratch everything isn't worthwhile but when this is already done in a Delphi way, why don't use it?
Use service with a timer that is fired regulary (for example each minute). It reads the schedule and looks if some are due before the next iteration. If so, you can execute them.
You can add an interface that shows all running apps. For the feedback and query that using a desktop application.

Does Application.ApplicationExit event work to be notified of exit in non-Winforms apps?

Our code library needs to be notified when the application is exiting. So we have subscribed to the System.Window.Forms.Application.ApplicationExit event. This works nicely for Winforms apps, but does it also work for other types of applications such as console apps, services, and web apps (such as ASP.NET)? The namespace would suggest that it doesn't, and it presumably gets raised when Application.Exit() is called (explicitly or implictly), which may not be correct to call for these other cases.
Is there some other event which would be better in these other cases or which would be more universal (great if it works for Winforms, too)? For example, is there an event for when Environment.Exit() is called (console app)?
I found a mention of an Exited event in System.Diagnostic.Process, but this appears to be for monitoring the exit of another process, and it does not appear to be received by a process about itself (for example, Process.GetCurrentProcess().Exited += Process_Exited; Process.GetCurrentProcess().EnableRaisingEvents = true;). I would think it might only be raised after the process has actually exited, so that wouldn't work.
This is particularly for .NET 2.0 and C#.
We finally found more about this (but by then my machine had been rebuilt and lost the cookies to my unregistered profile here; hopefully, it will let met post this answer).
Further investigation eventually found a few more events which we have found helpful:
System.Windows.Forms.Application.ThreadExit - Fires when a message loop exits
System.Windows.Forms.Application.ApplicationExit - Fires when all message loops exit
System.AppDomain.CurrentDomain.DomainUnload - Fires when a domain other than the default exits
System.AppDomain.CurrentDomain.ProcessExit - Fires when the default app domain exits
System.AppDomain.CurrentDomain.UnhandledException - Fires when an uncaught exception occurs, ending the app.
Only one of the DomainUnload or ProcessExit events are possible for a given app domain, depending on whether it is the default (top-level) domain for the process or was created as a subdomain (eg. on a web server). If an application doesn't know which it might be (as in our case), it needs to subscribe to both if it wants to catch the actual unload for itself. Also, it appears that UnhandledException (which as of .NET2.0 is always fatal) may prevent the other two events, so that may be a third case to handle. These three events should work for any .NET application.
There is a caveat that the execution time for ProcessExit is bounded (about 4 seconds?), so it may not be possible to do extensive "final" work in that event handler. It needs to be something which can be done quickly.
The Application events only apply to WinForms applications (we suspect they may not apply in pure WPF applications, however). The naming can be misleading because they are named for their most basic normal usage which has certain assumptions. ThreadExit does not relate to the actual System.Threading.Thread but rather to the message loop (Application.Run())) of a UI thread, and ApplicationExit similarly relates to the collection of application Forms on one or more UI threads. Normally, once the call to Application.Run() returns, called from the entry method of a thread, the entry method quickly concludes and the thread itself then ends. And once all UI threads have exited, a WinForms app is usually all done and exits.
Another event of note is the System.Windows.Forms.Application.ThreadException event. A Windows message loop can be configured to catch exceptions which occur in handling a message and send this event rather than let them be uncaught (and thus fatal) exceptions. Catching these exceptions allows the message loop (and that UI thread) to continue running (after aborting the current message handler). There can be only one subscriber to this event at any time for a given thread (subscriptions overwrite any previous subscriber), and it must be configured before any Form is created and subscribed before entering the message loop. See the MSDN help for this event and System.Windows.Forms.Applicaton.SetUnhandledExceptionMode() for more info.

Resources