diff --git a/RadeonResetBugFixService/ConsoleHelper.cs b/RadeonResetBugFixService/ConsoleHelper.cs
deleted file mode 100644
index c9010a8..0000000
--- a/RadeonResetBugFixService/ConsoleHelper.cs
+++ /dev/null
@@ -1,23 +0,0 @@
-namespace RadeonResetBugFixService
-{
- using System;
- using System.Runtime.InteropServices;
-
- static class ConsoleHelper
- {
- private static class NativeMethods
- {
- [DllImport("kernel32.dll")]
- public static extern IntPtr GetConsoleWindow();
-
- [DllImport("user32.dll")]
- public static extern bool IsWindowVisible(IntPtr hWnd);
- }
-
- // Code taken from https://stackoverflow.com/a/53716169
- public static bool HaveVisibleConsole()
- {
- return NativeMethods.IsWindowVisible(NativeMethods.GetConsoleWindow());
- }
- }
-}
diff --git a/RadeonResetBugFixService/EnvironmentHelper.cs b/RadeonResetBugFixService/EnvironmentHelper.cs
new file mode 100644
index 0000000..32d69e3
--- /dev/null
+++ b/RadeonResetBugFixService/EnvironmentHelper.cs
@@ -0,0 +1,39 @@
+namespace RadeonResetBugFixService
+{
+ using System;
+ using System.Runtime.InteropServices;
+ using System.Security.Principal;
+
+ static class EnvironmentHelper
+ {
+ private static class NativeMethods
+ {
+ [DllImport("kernel32.dll")]
+ public static extern IntPtr GetConsoleWindow();
+
+ [DllImport("user32.dll")]
+ public static extern bool IsWindowVisible(IntPtr hWnd);
+ }
+
+ private static Version VistaVersion { get; } = new Version(6, 0);
+
+ private static Version Windows8Version { get; } = new Version(6, 2);
+
+ // Code taken from https://stackoverflow.com/a/53716169
+ public static bool IsConsoleVisibleOnWindows() => NativeMethods.IsWindowVisible(NativeMethods.GetConsoleWindow());
+
+ private static bool IsWindows() => RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
+
+ // Code taken from https://stackoverflow.com/a/2679654
+ public static bool HasAdministratorPrivileges()
+ {
+ WindowsIdentity id = WindowsIdentity.GetCurrent();
+ WindowsPrincipal principal = new WindowsPrincipal(id);
+ return principal.IsInRole(WindowsBuiltInRole.Administrator);
+ }
+
+ public static bool IsWindows8OrNewer() => IsWindows() && Environment.OSVersion.Version >= Windows8Version;
+
+ public static bool IsVistaOrNewer() => IsWindows() && Environment.OSVersion.Version >= VistaVersion;
+ }
+}
diff --git a/RadeonResetBugFixService/Program.cs b/RadeonResetBugFixService/Program.cs
index 79f6adb..cb1ed5a 100644
--- a/RadeonResetBugFixService/Program.cs
+++ b/RadeonResetBugFixService/Program.cs
@@ -1,8 +1,6 @@
namespace RadeonResetBugFixService
{
using System;
- using System.Runtime.InteropServices;
- using System.Security.Principal;
using System.ServiceProcess;
using ThirdParty.ServiceHelpers;
@@ -18,15 +16,15 @@
throw new ArgumentNullException(nameof(args));
}
- if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+ if (!EnvironmentHelper.IsVistaOrNewer())
{
- Console.Error.WriteLine("This program only runs on Windows");
+ Console.Error.WriteLine("This program only runs on Windows Vista or newer");
return -1;
}
- if (ConsoleHelper.HaveVisibleConsole())
+ if (EnvironmentHelper.IsConsoleVisibleOnWindows())
{
- if (!HasAdministratorPrivileges())
+ if (!EnvironmentHelper.HasAdministratorPrivileges())
{
Console.Error.WriteLine("Access Denied.");
Console.Error.WriteLine("Administrator permissions are needed to use this tool.");
@@ -43,14 +41,10 @@
}
}
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope", Justification = "Windows service initialization")]
private static int MainService()
{
- ServiceBase[] ServicesToRun;
- ServicesToRun = new ServiceBase[]
- {
- new RadeonResetBugFixService()
- };
- ServiceBase.Run(ServicesToRun);
+ ServiceBase.Run(new RadeonResetBugFixService());
return 0;
}
@@ -142,13 +136,5 @@
{
new MainHandler().HandleShutdown("Program.DoShutdown");
}
-
- // Code taken from https://stackoverflow.com/a/2679654
- private static bool HasAdministratorPrivileges()
- {
- WindowsIdentity id = WindowsIdentity.GetCurrent();
- WindowsPrincipal principal = new WindowsPrincipal(id);
- return principal.IsInRole(WindowsBuiltInRole.Administrator);
- }
}
}
diff --git a/RadeonResetBugFixService/Properties/app.manifest b/RadeonResetBugFixService/Properties/app.manifest
new file mode 100644
index 0000000..9abde23
--- /dev/null
+++ b/RadeonResetBugFixService/Properties/app.manifest
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/RadeonResetBugFixService/RadeonResetBugFixService.cs b/RadeonResetBugFixService/RadeonResetBugFixService.cs
index 1893de0..9062787 100644
--- a/RadeonResetBugFixService/RadeonResetBugFixService.cs
+++ b/RadeonResetBugFixService/RadeonResetBugFixService.cs
@@ -92,12 +92,15 @@
"ServiceBase.OnCustomCommand",
(string reason) =>
{
- this.Handler.HandleLog($"Custom command: {command}");
-
if (command == SERVICE_CONTROL_PRESHUTDOWN)
{
+ this.Handler.HandleLog($"Custom command: preshutdown");
this.CallStop();
}
+ else
+ {
+ this.Handler.HandleLog($"Unknown custom command: {command}");
+ }
});
}
diff --git a/RadeonResetBugFixService/RadeonResetBugFixService.csproj b/RadeonResetBugFixService/RadeonResetBugFixService.csproj
index 40855ee..b6e6e21 100644
--- a/RadeonResetBugFixService/RadeonResetBugFixService.csproj
+++ b/RadeonResetBugFixService/RadeonResetBugFixService.csproj
@@ -44,6 +44,9 @@
+
+ Properties\app.manifest
+
@@ -58,7 +61,7 @@
-
+
@@ -106,6 +109,7 @@
+
diff --git a/RadeonResetBugFixService/RegistryHelper.cs b/RadeonResetBugFixService/RegistryHelper.cs
index 69867d1..820d9cb 100644
--- a/RadeonResetBugFixService/RegistryHelper.cs
+++ b/RadeonResetBugFixService/RegistryHelper.cs
@@ -19,15 +19,21 @@
}
}
- private static RegistryValuePath PreshutdownOrderPath = new RegistryValuePath(@"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control", "PreshutdownOrder");
+ private static string BasicDisplayServiceName { get; } = (
+ EnvironmentHelper.IsWindows8OrNewer()
+ ? "BasicDisplay"
+ : "vga"
+ );
- private static RegistryValuePath WaitToKillServiceTimeoutPath = new RegistryValuePath(@"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control", "WaitToKillServiceTimeout");
+ private static RegistryValuePath PreshutdownOrderPath { get; } = new RegistryValuePath(@"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control", "PreshutdownOrder");
- private static RegistryValuePath FastRebootPath = new RegistryValuePath(@"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Power", "HiberbootEnabled");
+ private static RegistryValuePath WaitToKillServiceTimeoutPath { get; } = new RegistryValuePath(@"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control", "WaitToKillServiceTimeout");
- private static RegistryValuePath NoInteractiveServicesPath = new RegistryValuePath(@"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Windows", "NoInteractiveServices");
+ private static RegistryValuePath FastRebootPath { get; } = new RegistryValuePath(@"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Power", "HiberbootEnabled");
- private static RegistryValuePath BasicDisplayStartTypePath = new RegistryValuePath(@"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\BasicDisplay", "Start");
+ private static RegistryValuePath NoInteractiveServicesPath { get; } = new RegistryValuePath(@"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Windows", "NoInteractiveServices");
+
+ private static RegistryValuePath BasicDisplayStartTypePath { get; } = new RegistryValuePath(@"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\" + BasicDisplayServiceName, "Start");
private static T GetValue(RegistryValuePath path, T defaultValue = default) => (T)Registry.GetValue(path.KeyName, path.ValueName, defaultValue);