0

I have a Windows Service built in C# using .NET which every time a user logs off, suspends, sleeps resets or powers down it throws an error. In the Application Event Viewer it shows the error as this :-

Application: Service.exe
Framework Version: v4.0.30319
Description: The process was terminated due to an unhandled exception.
Exception Info: System.ComponentModel.Win32Exception

Exception Info: System.InvalidOperationException
   at System.ServiceProcess.ServiceController.GenerateNames()
   at System.ServiceProcess.ServiceController.get_ServiceName()
   at System.ServiceProcess.ServiceController.Stop()
   at WellformationDesktopService.Wellformation+<OnSessionChange>d__3.MoveNext()
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore+<>c.<ThrowAsync>b__6_1(System.Object)
   at System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(System.Object)
   at System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
   at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
   at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
   at System.Threading.ThreadPoolWorkQueue.Dispatch()
   at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()

The action that seems to be failing is using a System.Net.HTTP.HttpClient to send a submission to remote API. The code works at any other time other than when Windows is in effect shutting down the user space.

What do I need to do to force my service to fire the action before it is not possible to do?

Thanks in advance.

Rich G
  • 103
  • 1
  • 7
  • Listen https://stackoverflow.com/questions/5202119/detect-shutdown-in-window-service https://learn.microsoft.com/en-us/dotnet/api/microsoft.win32.systemevents.powermodechanged and handle them in your loop (with cancellationtoken etc). Though for suspend, it's unlikely you can handle the event fast enough before Windows actually suspend itself, so perhaps just catch the exception – Martheen Jun 02 '21 at 10:25
  • In this case, would it be better to periodically read the windows event logs and forward that information, while it means we will be a little behind with receiving the information (power down may not be received until the next day) at least we will capture all the appropriate events? – Rich G Jun 02 '21 at 14:22
  • Yeah, that's possible. Beware of the race condition where your service is shut down before it receives 204 (or whatever return you set for successful submission) and think it failed, so your remote service must have a way to handle it. – Martheen Jun 02 '21 at 14:42

2 Answers2

0

You can create a .ps (powershell script) to check your services to be stopped and the script forces to run your windows services.

The following script will solve your problem.

# start the following Windows services in the specified order:
[Array] $Services = 'Service1','Service2','Service3',...;

# loop through each service, if its running, start it
foreach($ServiceName in $Services)
{
    $arrService = Get-Service -Name $ServiceName
    write-host $ServiceName
    while ($arrService.Status -eq 'Stopped')
    {
        Start-Service $ServiceName
        write-host $arrService.status
        write-host 'Service starting'
        Start-Sleep -seconds 60
        $arrService.Refresh()
        if ($arrService.Status -eq 'Running')
            {
              Write-Host 'Service is now Running'
            }
     }
 }

You can run this script whenever you want by periodically via Windows Task Scheduler.

And how to set Windows Service startup type Automatically.

Windows Service Start Automatically

  • Unfortunately this application needs to run in a secure user environment and I cannot be launching PS scripts as that would require elevated permissions beyond those allowed to the windows services currently. – Rich G Jun 03 '21 at 14:07
  • @RichG The administrator permission is required for more operational processes such as windows service management, etc. I don't know a solution how to control windows service via C# but your system administrator can set your windows service Startup type to Automatically that provides when the machine restarts your windows service runs automatically. I added a link how to do it to my answer. – Anıl Ayaydın Jun 03 '21 at 16:20
0

We have corrected the issue as per the advice from @Martheen above and all is now working. We ignore the windows shut down events but on startup find the last logout for a user and use that time for the end of their session and submit it in retrospect the next time the machine is used.

Thanks

Rich G
  • 103
  • 1
  • 7