Radeon Reset Bug fix service
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
RadeonResetBugFix/RadeonResetBugFixService/RadeonResetBugFixService.cs

110 lines
3.7 KiB

namespace RadeonResetBugFixService
{
using System;
using System.Reflection;
using System.ServiceProcess;
using Microsoft.Win32;
using Contracts;
using Tasks.ComplexTasks;
public partial class RadeonResetBugFixService : ServiceBase
{
private ServiceContext Context { get; } = new ServiceContext();
private MainHandler Handler { get; } = new MainHandler();
public RadeonResetBugFixService()
{
InitializeComponent();
this.EnablePreshutdown();
}
private void EnablePreshutdown()
{
const int SERVICE_ACCEPT_PRESHUTDOWN = 0x100;
var acceptedCommandsFieldInfo = typeof(ServiceBase).GetField("acceptedCommands", BindingFlags.Instance | BindingFlags.NonPublic);
if (acceptedCommandsFieldInfo == null)
{
throw new Exception("acceptedCommands field not found");
}
var value = (int)acceptedCommandsFieldInfo.GetValue(this);
acceptedCommandsFieldInfo.SetValue(this, value | SERVICE_ACCEPT_PRESHUTDOWN);
}
private void CallStop()
{
var deferredStopMethodInfo = typeof(ServiceBase).GetMethod("DeferredStop", BindingFlags.Instance | BindingFlags.NonPublic);
deferredStopMethodInfo.Invoke(this, null);
}
protected override void OnShutdown()
{
this.Handler.HandleEntryPoint(
"ServiceBase.OnShutdown",
(logger) => this.CallStop()
);
}
protected override void OnStart(string[] args)
{
this.Handler.HandleEntryPoint(
"ServiceBase.OnStart",
(logger) =>
{
this.RequestAdditionalTime((int)Constants.ServiceTimeout.TotalMilliseconds);
TasksProcessor.ProcessTask(logger, new StartupTask(this.Context));
this.EnablePreshutdown();
SystemEvents.SessionEnding += this.OnSessionEnding;
});
}
protected override void OnStop()
{
this.Handler.HandleEntryPoint(
"ServiceBase.OnStop",
(logger) =>
{
this.RequestAdditionalTime((int)Constants.ServiceTimeout.TotalMilliseconds);
TasksProcessor.ProcessTask(logger, new ShutdownTask(this.Context));
SystemEvents.SessionEnding -= this.OnSessionEnding;
});
}
protected override void OnCustomCommand(int command)
{
const int SERVICE_CONTROL_PRESHUTDOWN = 0xf;
this.Handler.HandleEntryPoint(
"ServiceBase.OnCustomCommand",
(logger) =>
{
if (command == SERVICE_CONTROL_PRESHUTDOWN)
{
logger.Log("Custom command: preshutdown");
this.CallStop();
}
else
{
logger.Log("Unknown custom command: {command}");
}
});
}
private void OnSessionEnding(object sender, SessionEndingEventArgs args)
{
this.Handler.HandleEntryPoint(
"SystemEvents.OnSessionEnding",
(logger) =>
{
logger.Log($"Session end reason: ${args.Reason}");
if (args.Reason == SessionEndReasons.SystemShutdown)
{
TasksProcessor.ProcessTask(logger, new ShutdownTask(this.Context));
}
});
}
}
}