|
|
|
|
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));
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|