Aldaviva / PowerMate

🎛 Receive events and control the light on a Griffin PowerMate USB device
https://www.nuget.org/packages/PowerMate/
Apache License 2.0
6 stars 0 forks source link

FileNotFoundException crash on reboot #6

Open Aldaviva opened 4 months ago

Aldaviva commented 4 months ago

This happened 3 hours after the computer shut down unexpectedly due to a power outage, and I turned it back on when power was restored.

Faulting application name: PowerMateVolume.exe, version: 1.1.1.0, time stamp: 0x653067fb
Faulting module name: KERNELBASE.dll, version: 10.0.22621.3527, time stamp: 0x83efbeab
Exception code: 0xe0434352
Fault offset: 0x000000000006543c
Faulting process id: 0x0x2CA4
Faulting application start time: 0x0x1DAB19273BD0FD4
Faulting application path: C:\Programs\Accessories\PowerMateVolume.exe
Faulting module path: C:\WINDOWS\System32\KERNELBASE.dll
Report Id: d1d3859b-047a-436e-8d5d-59cc378b466e
Faulting package full name: 
Faulting package-relative application ID: 
Application: PowerMateVolume.exe
CoreCLR Version: 8.0.524.21615
.NET Version: 8.0.5
Description: The process was terminated due to an unhandled exception.
Exception Info: System.IO.FileNotFoundException: 
File name: 'System.Security.Principal.Windows, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
   at System.Diagnostics.Eventing.Reader.NativeWrapper.ConvertToObject(EvtVariant val)
   at System.Diagnostics.Eventing.Reader.NativeWrapper.EvtRenderBufferWithContextSystem(EventLogHandle contextHandle, EventLogHandle eventHandle, EvtRenderFlags flag, SystemProperties systemProperties)
   at System.Diagnostics.Eventing.Reader.EventLogRecord.PrepareSystemData()
   at System.Diagnostics.Eventing.Reader.EventLogRecord.get_Id()
   at PowerMateVolume.EventLogStandbyListener.onEventRecord(Object sender, EventRecordWrittenEventArgs e)
   at System.Diagnostics.Eventing.Reader.EventLogWatcher.HandleEventsRequestCompletion()
   at System.Diagnostics.Eventing.Reader.EventLogWatcher.RequestEvents()
   at System.Diagnostics.Eventing.Reader.EventLogWatcher.SubscribedEventsAvailableCallback(Object state, Boolean timedOut)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location ---
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.RegisteredWaitHandle.PerformCallback(Boolean timedOut)
   at System.Threading.ThreadPoolWorkQueue.Dispatch()
   at System.Threading.PortableThreadPool.WorkerThread.WorkerThreadStart()

The getter for EventLogRecord.Id threw the exception when called from EventLogStandbyListener.onEventRecord(object?, EventRecordWrittenEventArgs).

Running the program again manually later started fine.

The file C:\Program Files\dotnet\shared\Microsoft.NETCore.App\8.0.6\System.Security.Principal.Windows.dll exists on my computer and its Authenticode signature is valid. Maybe .NET 8.0.6 was in the middle of installing the very recent 8.0.6 update when my program launched during boot? This installation seems to have finished at 11:52 PM, before the crash. Maybe the lazy-loaded DLL file got pulled out from under my running process, and it crashed later when it tried to access it with the old runtime paths still in memory but the corresponding files gone from disk.

Aldaviva commented 4 months ago

I think the steps to reproduce this issue are

  1. Run PowerMateVolume
  2. Install a different version of the .NET runtime or desktop runtime, for example upgrading from 8.0.5 to 8.0.6.
  3. Put the computer to sleep
  4. Wake the computer up
  5. Check Task Manager and Event Viewer to see if PowerMateVolume crashed and if any Application errors were thrown.
Aldaviva commented 4 months ago

Aside from getting notified that a new version of .NET was installed somehow, I'm not sure how to avoid this problem automatically.

Aldaviva commented 4 months ago

Maybe you could start a file watcher for C:\Program Files\dotnet\shared\Microsoft.NETCore.App\8.0.6\hostpolicy.dll or whatever your process has loaded, and when it is deleted, take some action like restart the process with the same arguments, or call some other process like systemctl restart myservice.service or Restart-Service MyService.

Aldaviva commented 4 months ago

I'm going to attempt to solve this with Aldaviva/RuntimeUpgradeNotifier.