0

I am dabbling with Windows services.

From what I've read and the tutorials I've covered (one example) I see that all the work must be done in the OnStart method of the service.
As far as I understand it (from the only tutorials I was able to find, which were completely basic) after the OnStart method returns the service can't do anything if you haven't, somehow, configured it in the method.
I saw the use of timers in said method to trigger events every X seconds but what I am looking for is to detect window focus changes (when a program tries to bring its window to the front). The solution in this answer works perfectly when I try it in a console application but I want to use it in my service.

However, simply registering the eventhandler in the OnStart method does not work - it doesn't get triggered and has no effect. I tried putting a timer just to keep the OnStart method going but that didn't help, either - the timer was running and it was doing work each tick but the eventhandler never fired (I put a File.AppendText for each timer tick and each time the handler fires but in the text file I used as a control only the timer ticks were appended).
Lastly, I tried running a Task (by using Task.Run to create a new thread) which ran an endless loop in a separate method from OnStart but that just made the service start hang as it went on and on.

Code:

    protected override void OnStart(string[] args)
    {
        File.WriteAllText("file.txt", "START");
        eventLog.WriteEntry("Entered OnStart method.");

        // Update the service state to "Start Pending".
        ServiceStatus serviceStatus = new ServiceStatus
        {
            dwCurrentState = ServiceState.SERVICE_START_PENDING,
            dwWaitHint = 100000
        };
        SetServiceStatus(this.ServiceHandle, ref serviceStatus);

        eventLog.WriteEntry("Start Pending.", EventLogEntryType.Information);

        // Update the service state to "Running".
        serviceStatus.dwCurrentState = ServiceState.SERVICE_RUNNING;
        SetServiceStatus(this.ServiceHandle, ref serviceStatus);

        eventLog.WriteEntry("Running.", EventLogEntryType.Information);

        Task.Run(KeepBusy());
    }

    private static Action KeepBusy()
    {
        Automation.AddAutomationFocusChangedEventHandler(OnFocusChangedHandler);

        while (true)
        {
            Thread.Sleep(1000);
        }
    }

In short - if I correctly understand services can only perform work in the OnStart method I am disgusted at how stupid this seems and can't figure out how to make a "listener" service

J. Doe
  • 1,147
  • 1
  • 13
  • 21
  • In the `OnStart` method, you can create a background thread, that performs the necessary work, maybe in a loop. This is a widely used approach. Interactive services may be dangerous, see: https://learn.microsoft.com/en-us/windows/desktop/services/interactive-services – KBO Aug 29 '18 at 10:31
  • @KBO, thanks! I thought I did just that by using `Task.Run`? Let me edit the question a bit... – J. Doe Aug 29 '18 at 10:38
  • Actually, you are supposed to do as little as possible in OnStart. It should return as fast as possible. Mostly you'd just want to start off some background thread and maybe do some configuration and that's it. Everything else should be handled on that background thread. Without code it is impossible to provide useful help on how your code could be fixed. So it would be awesome if you could provide a [mcve] – Fildor Aug 29 '18 at 10:58
  • 1
    A service runs within an isolated session (so with its own desktop) & is fundamentally not supposed to interact with other users (i.e. your) desktops. It sounds like whatever you are doing is better suited to a per-user autorun application. – Alex K. Aug 29 '18 at 11:22
  • @Fildor, I know, sorry, I just thought since it's more of a principal question and I don't have any working code I'd be better to go without it. I'll try to add it tomorrow. – J. Doe Aug 29 '18 at 13:01
  • @AlexK., huh, if you say so, I'd scrap the project and retry with an application. – J. Doe Aug 29 '18 at 13:02

0 Answers0