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

122 lines
3.9 KiB

namespace RadeonResetBugFixService
{
using System;
using System.Reflection;
using System.ServiceProcess;
using Microsoft.Win32;
public partial class RadeonResetBugFixService : ServiceBase
{
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);
}
private void Process(string reason, Action<string> handle)
{
this.Handler.HandleLog($"{reason} initiated");
try
{
handle(reason);
this.Handler.HandleLog($"{reason} successfully finished");
}
catch (Exception e)
{
this.Handler.HandleLog($"{reason} error: {e}");
}
}
protected override void OnShutdown()
{
this.Process(
"ServiceBase.OnShutdown",
(string reason) =>
{
this.CallStop();
});
}
protected override void OnStart(string[] args)
{
this.Process(
"ServiceBase.OnStart",
(string reason) =>
{
this.RequestAdditionalTime((int)Constants.ServiceTimeout.TotalMilliseconds);
this.Handler.HandleStartup(reason);
this.EnablePreshutdown();
SystemEvents.SessionEnding += this.OnSessionEnding;
});
}
protected override void OnStop()
{
this.Process(
"ServiceBase.OnStop",
(string reason) =>
{
this.RequestAdditionalTime((int)Constants.ServiceTimeout.TotalMilliseconds);
this.Handler.HandleShutdown(reason);
SystemEvents.SessionEnding -= this.OnSessionEnding;
});
}
protected override void OnCustomCommand(int command)
{
const int SERVICE_CONTROL_PRESHUTDOWN = 0xf;
this.Process(
"ServiceBase.OnCustomCommand",
(string reason) =>
{
if (command == SERVICE_CONTROL_PRESHUTDOWN)
{
this.Handler.HandleLog($"Custom command: preshutdown");
this.CallStop();
}
else
{
this.Handler.HandleLog($"Unknown custom command: {command}");
}
});
}
private void OnSessionEnding(object sender, SessionEndingEventArgs args)
{
this.Process(
"SystemEvents.OnSessionEnding",
(string reason) =>
{
this.Handler.HandleLog($"Session end reason: ${args.Reason}");
if (args.Reason == SessionEndReasons.SystemShutdown)
{
this.Handler.HandleShutdown(reason);
}
});
}
}
}