UI improved

master v0.1.2
Inga 🏳‍🌈 4 years ago
parent c1b962a646
commit 361d47ef01
  1. 37
      README.md
  2. 8
      RadeonResetBugFixService/Constants.cs
  3. 4
      RadeonResetBugFixService/MainHandler.cs
  4. 47
      RadeonResetBugFixService/Program.cs
  5. 4
      RadeonResetBugFixService/ProjectInstaller.cs
  6. 20
      RadeonResetBugFixService/ThirdParty/ServiceHelpers.cs

@ -16,6 +16,11 @@ you find out that virtual GPU is now the primary display adapter,
GPU acceleration is unavailable, GPU acceleration is unavailable,
and the screen connected to Radeon GPU is treated as the secondary screen. and the screen connected to Radeon GPU is treated as the secondary screen.
This service intends to solve all the above problems.
With it, you will be able to use Radeon GPU as your only GPU,
with your actual display connected to Radeon as a primary display,
and reboot your VM without triggering AMD reset bug - even installing Windows updates!
## Limitations ## Limitations
Currently this project is only tested with Hyper-V VMs, Currently this project is only tested with Hyper-V VMs,
@ -23,17 +28,40 @@ and probably also supports KVM and QEMU,
but it should be trivial to add other hypervisors support but it should be trivial to add other hypervisors support
(the relevant files are `Tasks\DisableVirtualVideoTask.cs` and `EnableVirtualVideoTask.cs`). (the relevant files are `Tasks\DisableVirtualVideoTask.cs` and `EnableVirtualVideoTask.cs`).
**Note that you will still have to add a virtual GPU to your VM,
otherwise Windows won't boot.**
Note that it will add 1-5 minutes both to startup and to shutdown time.
So don't panic if your screen is black immediately after VM startup,
it is expected.
## Install instructions ## Install instructions
Put `RadeonResetBugFixService.exe` in a permanent location.
In elevated command prompt in Guest VM, run In elevated command prompt in Guest VM, run
``` ```
RadeonResetBugFixService.exe install RadeonResetBugFixService.exe install
``` ```
Then check that everything works correctly by opening Services (`services.msc`), The screen may go blank several times during the process.
locating Radeon Reset Bug Fix Service there and starting or restarting it. It may take up to 15 minutes total (but should take less than 5).
The display connected to Radeon GPU should go dark and then work again.
Do not remove the file after that, or the service won't be able to start or stop.
The `install` command does not create any copies, does not create a folder in `Program Files`,
it simply adds a service to Windows, but the service refers to the `exe` file you invoked.
## Upgrade instructions
In elevated command prompt in Guest VM, run
```
RadeonResetBugFixService.exe reinstall
```
The screen may go blank several times during the process.
It may take up to 20 minutes total (but should take less than 5).
## Uninstall instructions ## Uninstall instructions
@ -43,6 +71,9 @@ In elevated command prompt in Guest VM, run
RadeonResetBugFixService.exe uninstall RadeonResetBugFixService.exe uninstall
``` ```
The screen may go blank several times during the process.
It may take up to 5 minutes total (but should take less than 2).
## Debugging ## Debugging
The service stores its verbose log files in `logs` directory located next to the executable. The service stores its verbose log files in `logs` directory located next to the executable.

@ -1,9 +1,17 @@
namespace RadeonResetBugFixService namespace RadeonResetBugFixService
{ {
using System; using System;
using System.IO;
using System.Reflection;
static class Constants static class Constants
{ {
public static TimeSpan ServiceTimeout { get; } = TimeSpan.FromMinutes(5); public static TimeSpan ServiceTimeout { get; } = TimeSpan.FromMinutes(5);
public static string ServiceName { get; } = "RadeonResetBugFixService";
public static string LogDirectory { get; } = Path.Combine(
Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location),
"logs");
} }
} }

@ -2,7 +2,6 @@
{ {
using System; using System;
using System.IO; using System.IO;
using System.Reflection;
using Contracts; using Contracts;
using Logging; using Logging;
using Tasks; using Tasks;
@ -21,8 +20,7 @@
{ {
var date = DateTime.Now; var date = DateTime.Now;
this.LogFilename = Path.Combine( this.LogFilename = Path.Combine(
Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), Constants.LogDirectory,
"logs",
$"radeonfix_{date:yyyyMMdd}_{date:HHmmss}.log"); $"radeonfix_{date:yyyyMMdd}_{date:HHmmss}.log");
} }

@ -22,8 +22,8 @@
if (!HasAdministratorPrivileges()) if (!HasAdministratorPrivileges())
{ {
Console.Error.WriteLine("Access Denied."); Console.Error.WriteLine("Access Denied.");
Console.Error.WriteLine("Administrator permissions are needed to use the selected options."); Console.Error.WriteLine("Administrator permissions are needed to use this tool.");
Console.Error.WriteLine("Use an administrator command prompt to complete these tasks."); Console.Error.WriteLine("Run the command again from an administrator command prompt.");
return 740; // ERROR_ELEVATION_REQUIRED return 740; // ERROR_ELEVATION_REQUIRED
} }
@ -50,13 +50,8 @@
private static void MainConsole(string[] args) private static void MainConsole(string[] args)
{ {
if (args.Length != 1) var command = args.Length == 1 ? args[0] : string.Empty;
{
ShowHelp();
return;
}
var command = args[0];
if (command.Equals("install", StringComparison.OrdinalIgnoreCase)) { if (command.Equals("install", StringComparison.OrdinalIgnoreCase)) {
DoInstall(); DoInstall();
} }
@ -64,6 +59,10 @@
{ {
DoUninstall(); DoUninstall();
} }
else if (command.Equals("reinstall", StringComparison.OrdinalIgnoreCase))
{
DoReinstall();
}
else if (command.Equals("startup", StringComparison.OrdinalIgnoreCase)) else if (command.Equals("startup", StringComparison.OrdinalIgnoreCase))
{ {
DoStartup(); DoStartup();
@ -72,6 +71,10 @@
{ {
DoShutdown(); DoShutdown();
} }
else
{
ShowHelp();
}
} }
private static void ShowHelp() private static void ShowHelp()
@ -82,10 +85,12 @@
Console.WriteLine("\t\tInstalls service"); Console.WriteLine("\t\tInstalls service");
Console.WriteLine($"\t{exeName} uninstall"); Console.WriteLine($"\t{exeName} uninstall");
Console.WriteLine("\t\tUninstalls service"); Console.WriteLine("\t\tUninstalls service");
Console.WriteLine($"\t{exeName} reinstall");
Console.WriteLine("\t\tReinstalls service (might be useful for some upgrades)");
Console.WriteLine($"\t{exeName} startup"); Console.WriteLine($"\t{exeName} startup");
Console.WriteLine("\t\tPerforms startup sequence"); Console.WriteLine("\t\tPerforms startup sequence (development command, does not affect services)");
Console.WriteLine($"\t{exeName} shutdown"); Console.WriteLine($"\t{exeName} shutdown");
Console.WriteLine("\t\tPerforms shutdown sequence"); Console.WriteLine("\t\tPerforms shutdown sequence (development command, does not affect services)");
} }
private static void DoInstall() private static void DoInstall()
@ -93,21 +98,33 @@
Console.WriteLine("Setting registry values..."); Console.WriteLine("Setting registry values...");
Console.WriteLine("Installing service..."); Console.WriteLine("Installing service...");
ServiceHelpers.InstallService(nameof(RadeonResetBugFixService), typeof(RadeonResetBugFixService)); ServiceHelpers.InstallService(Constants.ServiceName, typeof(RadeonResetBugFixService));
Console.WriteLine("Starting service..."); Console.WriteLine("Starting service...");
ServiceHelpers.StartService(nameof(RadeonResetBugFixService)); ServiceHelpers.StartService(Constants.ServiceName);
Console.WriteLine("Started service"); Console.WriteLine("Should restart service now; stopping service...");
ServiceHelpers.StopService(Constants.ServiceName);
Console.WriteLine("Starting service...");
ServiceHelpers.StartService(Constants.ServiceName);
} }
private static void DoUninstall() private static void DoUninstall()
{ {
Console.WriteLine("Stopping service..."); Console.WriteLine("Stopping service...");
ServiceHelpers.StopService(nameof(RadeonResetBugFixService)); ServiceHelpers.StopService(Constants.ServiceName);
Console.WriteLine("Uninstalling service..."); Console.WriteLine("Uninstalling service...");
ServiceHelpers.UninstallService(nameof(RadeonResetBugFixService), typeof(RadeonResetBugFixService)); ServiceHelpers.UninstallService(Constants.ServiceName, typeof(RadeonResetBugFixService));
Console.WriteLine("Uninstalled"); Console.WriteLine("Uninstalled");
} }
private static void DoReinstall()
{
Console.WriteLine("Attempting to uninstall...");
DoUninstall();
Console.WriteLine("Attempting to install...");
DoInstall();
}
private static void DoStartup() private static void DoStartup()
{ {
new MainHandler().HandleStartup("Program.DoStartup"); new MainHandler().HandleStartup("Program.DoStartup");

@ -3,6 +3,7 @@
using System; using System;
using System.ComponentModel; using System.ComponentModel;
using System.Configuration.Install; using System.Configuration.Install;
using System.IO;
using System.Linq; using System.Linq;
using System.Management; using System.Management;
@ -16,6 +17,9 @@
private void serviceInstaller1_AfterInstall(object sender, InstallEventArgs e) private void serviceInstaller1_AfterInstall(object sender, InstallEventArgs e)
{ {
Console.WriteLine($"Creating log directory ({Constants.LogDirectory})");
Directory.CreateDirectory(Constants.LogDirectory);
Console.WriteLine("Preventing Windows from killing services that take up to 300 seconds to shutdown"); Console.WriteLine("Preventing Windows from killing services that take up to 300 seconds to shutdown");
RegistryHelper.SetWaitToKillServiceTimeout((int)Constants.ServiceTimeout.TotalMilliseconds); RegistryHelper.SetWaitToKillServiceTimeout((int)Constants.ServiceTimeout.TotalMilliseconds);

@ -36,8 +36,10 @@
public static AssemblyInstaller GetInstaller(Type serviceType) public static AssemblyInstaller GetInstaller(Type serviceType)
{ {
AssemblyInstaller installer = new AssemblyInstaller(serviceType.Assembly, null); AssemblyInstaller installer = new AssemblyInstaller(serviceType.Assembly, null)
installer.UseNewContext = true; {
UseNewContext = true
};
return installer; return installer;
} }
@ -74,7 +76,7 @@
{ {
if (!IsInstalled(serviceName)) if (!IsInstalled(serviceName))
{ {
Console.WriteLine("Service not installed"); Console.WriteLine("Service not installed; nothing to uninstall");
return; return;
} }
@ -94,7 +96,11 @@
public static void StartService(string serviceName) public static void StartService(string serviceName)
{ {
if (!IsInstalled(serviceName)) return; if (!IsInstalled(serviceName))
{
Console.WriteLine("Service not installed; nothing to start");
return;
}
using (ServiceController controller = new ServiceController(serviceName)) using (ServiceController controller = new ServiceController(serviceName))
{ {
@ -108,7 +114,11 @@
public static void StopService(string serviceName) public static void StopService(string serviceName)
{ {
if (!IsInstalled(serviceName)) return; if (!IsInstalled(serviceName))
{
Console.WriteLine("Service not installed; nothing to stop");
return;
}
using (ServiceController controller = new ServiceController(serviceName)) using (ServiceController controller = new ServiceController(serviceName))
{ {

Loading…
Cancel
Save