Code cleanup

master
Inga 🏳‍🌈 4 years ago
parent 0fc4127589
commit b25932247e
  1. 7
      RadeonResetBugFixService/.editorconfig
  2. 4
      RadeonResetBugFixService/Constants.cs
  3. 27
      RadeonResetBugFixService/Devices/DeviceHelper.cs
  4. 7
      RadeonResetBugFixService/Devices/KnownDevices.cs
  5. 4
      RadeonResetBugFixService/MainHandler.cs
  6. 49
      RadeonResetBugFixService/Program.cs
  7. 1
      RadeonResetBugFixService/ProjectInstaller.Designer.cs
  8. 58
      RadeonResetBugFixService/ProjectInstaller.cs
  9. 31
      RadeonResetBugFixService/RadeonResetBugFixService.csproj
  10. 56
      RadeonResetBugFixService/RegistryHelper.cs
  11. 72
      RadeonResetBugFixService/Tasks/AbstractServiceTask.cs
  12. 4
      RadeonResetBugFixService/Tasks/DisableAmdVideoTask.cs
  13. 5
      RadeonResetBugFixService/Tasks/DisableBasicDisplayStartupTask.cs
  14. 5
      RadeonResetBugFixService/Tasks/EnableBasicDisplayStartupTask.cs
  15. 5
      RadeonResetBugFixService/Tasks/FixMonitorTask.cs
  16. 9
      RadeonResetBugFixService/Tasks/StopAudioServiceTask.cs
  17. 9
      RadeonResetBugFixService/ThirdParty/DisableDevice.cs
  18. 6
      RadeonResetBugFixService/ThirdParty/MonitorChanger.cs
  19. 9
      RadeonResetBugFixService/ThirdParty/ServiceHelpers.cs
  20. 6
      RadeonResetBugFixService/ThirdParty/ServicePreshutdownHelpers.cs
  21. 8
      RadeonResetBugFixService/packages.config

@ -0,0 +1,7 @@
[*.cs]
# CA1303: Do not pass literals as localized parameters
dotnet_diagnostic.CA1303.severity = suggestion
# CA1031: Do not catch general exception types
dotnet_diagnostic.CA1031.severity = suggestion

@ -5,9 +5,5 @@
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 RegistryKeyBasicDisplay { get; } = @"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\BasicDisplay";
public static string RegistryKeySystemControl { get; } = @"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control";
} }
} }

@ -3,7 +3,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Management; using System.Management;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Contracts; using Contracts;
@ -23,8 +22,12 @@
private static Guid GuidTryParse(string input) private static Guid GuidTryParse(string input)
{ {
Guid.TryParse(input, out var result); if (Guid.TryParse(input, out var result))
return result; {
return result;
}
return default;
} }
private static DeviceInfo ConvertDeviceInfo(PropertyDataCollection deviceProperties) private static DeviceInfo ConvertDeviceInfo(PropertyDataCollection deviceProperties)
@ -93,25 +96,9 @@
private static void RunWithTimeout(Action action, TimeSpan timeout) private static void RunWithTimeout(Action action, TimeSpan timeout)
{ {
Exception localException = null;
Task.WaitAny( Task.WaitAny(
Task.Run(() => Task.Run(action),
{
try
{
action();
}
catch (Exception e)
{
localException = new Exception("Exception from action", e);
}
}),
Task.Delay(timeout)); Task.Delay(timeout));
if (localException != null)
{
throw localException;
}
} }
} }
} }

@ -1,18 +1,19 @@
namespace RadeonResetBugFixService.Devices namespace RadeonResetBugFixService.Devices
{ {
using System;
using Contracts; using Contracts;
static class KnownDevices static class KnownDevices
{ {
public static bool IsAmdVideo(DeviceInfo device) public static bool IsAmdVideo(DeviceInfo device)
{ {
return (device.Manufacturer.ToLowerInvariant() == "amd" || device.Manufacturer.ToLowerInvariant().Contains("advanced micro devices")) && return ((device.Manufacturer.Equals("AMD", StringComparison.OrdinalIgnoreCase) || device.Manufacturer.IndexOf("Advanced Micro Devices", StringComparison.OrdinalIgnoreCase) >= 0) &&
(device.Service.ToLowerInvariant() == "hdaudbus" || device.ClassName.ToLowerInvariant() == "display"); (device.Service.Equals("hdaudbus", StringComparison.OrdinalIgnoreCase) || device.ClassName.Equals("display", StringComparison.OrdinalIgnoreCase)));
} }
public static bool IsVirtualVideo(DeviceInfo device) public static bool IsVirtualVideo(DeviceInfo device)
{ {
return device.Service.ToLowerInvariant() == "hypervideo"; return device.Service.Equals("hypervideo", StringComparison.OrdinalIgnoreCase);
} }
} }
} }

@ -50,10 +50,10 @@
new ITask[] new ITask[]
{ {
new EnableBasicDisplayStartupTask(), new EnableBasicDisplayStartupTask(),
new SleepTask(TimeSpan.FromSeconds(20)), new SleepTask(TimeSpan.FromSeconds(40)),
new EnableAmdVideoTask(this.StartupDevicesStatus), new EnableAmdVideoTask(this.StartupDevicesStatus),
new DisableVirtualVideoTask(this.StartupDevicesStatus), new DisableVirtualVideoTask(this.StartupDevicesStatus),
new SleepTask(TimeSpan.FromSeconds(40)), new SleepTask(TimeSpan.FromSeconds(20)),
new FixMonitorTask(), new FixMonitorTask(),
new DisableVirtualVideoTask(this.StartupDevicesStatus), new DisableVirtualVideoTask(this.StartupDevicesStatus),
new FixMonitorTask(), new FixMonitorTask(),

@ -1,6 +1,5 @@
namespace RadeonResetBugFixService namespace RadeonResetBugFixService
{ {
using Microsoft.Win32;
using System; using System;
using System.Security.Principal; using System.Security.Principal;
using System.ServiceProcess; using System.ServiceProcess;
@ -13,6 +12,11 @@
/// </summary> /// </summary>
public static int Main(string[] args) public static int Main(string[] args)
{ {
if (args == null)
{
throw new ArgumentNullException(nameof(args));
}
if (Environment.UserInteractive) if (Environment.UserInteractive)
{ {
if (!HasAdministratorPrivileges()) if (!HasAdministratorPrivileges())
@ -52,23 +56,21 @@
return; return;
} }
switch (args[0].ToLowerInvariant()) var command = args[0];
if (command.Equals("install", StringComparison.OrdinalIgnoreCase)) {
DoInstall();
}
else if (command.Equals("uninstall", StringComparison.OrdinalIgnoreCase))
{
DoUninstall();
}
else if (command.Equals("startup", StringComparison.OrdinalIgnoreCase))
{ {
case "install": DoStartup();
DoInstall(); }
return; else if (command.Equals("shutdown", StringComparison.OrdinalIgnoreCase))
case "uninstall": {
DoUninstall(); DoShutdown();
return;
case "startup":
DoStartup();
return;
case "shutdown":
DoShutdown();
return;
default:
ShowHelp();
return;
} }
} }
@ -90,26 +92,17 @@
{ {
Console.WriteLine("Setting registry values..."); Console.WriteLine("Setting registry values...");
// Prevent Windows from killing services that take up to 300 seconds to shutdown
Registry.SetValue(@"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control", "WaitToKillServiceTimeout", (int)Constants.ServiceTimeout.TotalMilliseconds, RegistryValueKind.String);
// Disable fast restart
Registry.SetValue(@"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Power", "HiberbootEnabled", 0, RegistryValueKind.DWord);
// Allow interactive services (FixMonitorTask only works correctly in interactive mode)
Registry.SetValue(@"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Windows", "NoInteractiveServices", 0, RegistryValueKind.DWord);
Console.WriteLine("Installing service..."); Console.WriteLine("Installing service...");
ServiceHelpers.InstallService(nameof(RadeonResetBugFixService), typeof(RadeonResetBugFixService)); ServiceHelpers.InstallService(nameof(RadeonResetBugFixService), typeof(RadeonResetBugFixService));
Console.WriteLine("Starting service..."); Console.WriteLine("Starting service...");
ServiceHelpers.StartService(nameof(RadeonResetBugFixService), typeof(RadeonResetBugFixService)); ServiceHelpers.StartService(nameof(RadeonResetBugFixService));
Console.WriteLine("Started service"); Console.WriteLine("Started service");
} }
private static void DoUninstall() private static void DoUninstall()
{ {
Console.WriteLine("Stopping service..."); Console.WriteLine("Stopping service...");
ServiceHelpers.StopService(nameof(RadeonResetBugFixService), typeof(RadeonResetBugFixService)); ServiceHelpers.StopService(nameof(RadeonResetBugFixService));
Console.WriteLine("Uninstalling service..."); Console.WriteLine("Uninstalling service...");
ServiceHelpers.UninstallService(nameof(RadeonResetBugFixService), typeof(RadeonResetBugFixService)); ServiceHelpers.UninstallService(nameof(RadeonResetBugFixService), typeof(RadeonResetBugFixService));
Console.WriteLine("Uninstalled"); Console.WriteLine("Uninstalled");

@ -36,7 +36,6 @@
this.serviceProcessInstaller1.Account = System.ServiceProcess.ServiceAccount.LocalSystem; this.serviceProcessInstaller1.Account = System.ServiceProcess.ServiceAccount.LocalSystem;
this.serviceProcessInstaller1.Password = null; this.serviceProcessInstaller1.Password = null;
this.serviceProcessInstaller1.Username = null; this.serviceProcessInstaller1.Username = null;
this.serviceProcessInstaller1.AfterInstall += new System.Configuration.Install.InstallEventHandler(this.serviceProcessInstaller1_AfterInstall);
// //
// serviceInstaller1 // serviceInstaller1
// //

@ -1,10 +1,10 @@
namespace RadeonResetBugFixService namespace RadeonResetBugFixService
{ {
using System;
using System.ComponentModel; using System.ComponentModel;
using System.Configuration.Install; using System.Configuration.Install;
using System.Linq; using System.Linq;
using System.Management; using System.Management;
using Microsoft.Win32;
[RunInstaller(true)] [RunInstaller(true)]
public partial class ProjectInstaller : System.Configuration.Install.Installer public partial class ProjectInstaller : System.Configuration.Install.Installer
@ -16,54 +16,44 @@
private void serviceInstaller1_AfterInstall(object sender, InstallEventArgs e) private void serviceInstaller1_AfterInstall(object sender, InstallEventArgs e)
{ {
ManagementObject wmiService = null; Console.WriteLine("Preventing Windows from killing services that take up to 300 seconds to shutdown");
ManagementBaseObject InParam = null; RegistryHelper.SetWaitToKillServiceTimeout((int)Constants.ServiceTimeout.TotalMilliseconds);
try
{ Console.WriteLine("Disabling fast reboot");
wmiService = new ManagementObject($"Win32_Service.Name='{this.serviceInstaller1.ServiceName}'"); RegistryHelper.SetFastRebootStatus(false);
InParam = wmiService.GetMethodParameters("Change");
InParam["DesktopInteract"] = true; Console.WriteLine("Allowing interactive services");
wmiService.InvokeMethod("Change", InParam, null); RegistryHelper.SetInteractiveServicesStatus(true);
}
finally Console.WriteLine("Configuring service as interactive");
using (var wmiService = new ManagementObject($"Win32_Service.Name='{this.serviceInstaller1.ServiceName}'"))
{ {
if (InParam != null) using (var InParam = wmiService.GetMethodParameters("Change"))
InParam.Dispose(); {
if (wmiService != null) InParam["DesktopInteract"] = true;
wmiService.Dispose(); wmiService.InvokeMethod("Change", InParam, null);
}
} }
Console.WriteLine("Setting preshutdown timeout for service");
ThirdParty.ServicePreshutdownHelpers.ServicePreshutdownHelpers.SetPreShutdownTimeOut(this.serviceInstaller1.ServiceName, (uint)Constants.ServiceTimeout.TotalMilliseconds); ThirdParty.ServicePreshutdownHelpers.ServicePreshutdownHelpers.SetPreShutdownTimeOut(this.serviceInstaller1.ServiceName, (uint)Constants.ServiceTimeout.TotalMilliseconds);
var preshutdownOrder = GetPreshutdownOrder(); Console.WriteLine("Adding service to preshutdown order");
var preshutdownOrder = RegistryHelper.GetPreshutdownOrder();
if (!preshutdownOrder.Contains(this.serviceInstaller1.ServiceName)) if (!preshutdownOrder.Contains(this.serviceInstaller1.ServiceName))
{ {
SetPreshutdownOrder(new[] { this.serviceInstaller1.ServiceName }.Concat(preshutdownOrder).ToArray()); RegistryHelper.SetPreshutdownOrder(new[] { this.serviceInstaller1.ServiceName }.Concat(preshutdownOrder).ToArray());
} }
} }
private void serviceInstaller1_AfterUninstall(object sender, InstallEventArgs e) private void serviceInstaller1_AfterUninstall(object sender, InstallEventArgs e)
{ {
var preshutdownOrder = GetPreshutdownOrder(); Console.WriteLine("Removing service from preshutdown order");
var preshutdownOrder = RegistryHelper.GetPreshutdownOrder();
if (preshutdownOrder.Contains(this.serviceInstaller1.ServiceName)) if (preshutdownOrder.Contains(this.serviceInstaller1.ServiceName))
{ {
SetPreshutdownOrder(preshutdownOrder.Where((name) => name != this.serviceInstaller1.ServiceName).ToArray()); RegistryHelper.SetPreshutdownOrder(preshutdownOrder.Where((name) => name != this.serviceInstaller1.ServiceName).ToArray());
} }
} }
private void serviceProcessInstaller1_AfterInstall(object sender, InstallEventArgs e)
{
}
private string[] GetPreshutdownOrder()
{
return (string[])Registry.GetValue(Constants.RegistryKeySystemControl, "PreshutdownOrder", new string[0]);
}
private void SetPreshutdownOrder(string[] data)
{
Registry.SetValue(Constants.RegistryKeySystemControl, "PreshutdownOrder", data, RegistryValueKind.MultiString);
}
} }
} }

@ -1,5 +1,10 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\packages\Microsoft.CodeAnalysis.FxCopAnalyzers.2.9.8\build\Microsoft.CodeAnalysis.FxCopAnalyzers.props" Condition="Exists('..\packages\Microsoft.CodeAnalysis.FxCopAnalyzers.2.9.8\build\Microsoft.CodeAnalysis.FxCopAnalyzers.props')" />
<Import Project="..\packages\Microsoft.NetFramework.Analyzers.2.9.8\build\Microsoft.NetFramework.Analyzers.props" Condition="Exists('..\packages\Microsoft.NetFramework.Analyzers.2.9.8\build\Microsoft.NetFramework.Analyzers.props')" />
<Import Project="..\packages\Microsoft.NetCore.Analyzers.2.9.8\build\Microsoft.NetCore.Analyzers.props" Condition="Exists('..\packages\Microsoft.NetCore.Analyzers.2.9.8\build\Microsoft.NetCore.Analyzers.props')" />
<Import Project="..\packages\Microsoft.CodeQuality.Analyzers.2.9.8\build\Microsoft.CodeQuality.Analyzers.props" Condition="Exists('..\packages\Microsoft.CodeQuality.Analyzers.2.9.8\build\Microsoft.CodeQuality.Analyzers.props')" />
<Import Project="..\packages\Microsoft.CodeAnalysis.VersionCheckAnalyzer.2.9.8\build\Microsoft.CodeAnalysis.VersionCheckAnalyzer.props" Condition="Exists('..\packages\Microsoft.CodeAnalysis.VersionCheckAnalyzer.2.9.8\build\Microsoft.CodeAnalysis.VersionCheckAnalyzer.props')" />
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup> <PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@ -12,6 +17,8 @@
<FileAlignment>512</FileAlignment> <FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects> <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Deterministic>true</Deterministic> <Deterministic>true</Deterministic>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget> <PlatformTarget>AnyCPU</PlatformTarget>
@ -73,6 +80,7 @@
<Compile Include="Program.cs" /> <Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Logging\TaskLoggerWrapper.cs" /> <Compile Include="Logging\TaskLoggerWrapper.cs" />
<Compile Include="RegistryHelper.cs" />
<Compile Include="Tasks\DisableBasicDisplayStartupTask.cs" /> <Compile Include="Tasks\DisableBasicDisplayStartupTask.cs" />
<Compile Include="Tasks\EnableBasicDisplayStartupTask.cs" /> <Compile Include="Tasks\EnableBasicDisplayStartupTask.cs" />
<Compile Include="Tasks\FixMonitorTask.cs" /> <Compile Include="Tasks\FixMonitorTask.cs" />
@ -94,7 +102,9 @@
<Compile Include="ThirdParty\ServicePreshutdownHelpers.cs" /> <Compile Include="ThirdParty\ServicePreshutdownHelpers.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include=".editorconfig" />
<None Include="App.config" /> <None Include="App.config" />
<None Include="packages.config" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<EmbeddedResource Include="ProjectInstaller.resx"> <EmbeddedResource Include="ProjectInstaller.resx">
@ -104,5 +114,26 @@
<DependentUpon>RadeonResetBugFixService.cs</DependentUpon> <DependentUpon>RadeonResetBugFixService.cs</DependentUpon>
</EmbeddedResource> </EmbeddedResource>
</ItemGroup> </ItemGroup>
<ItemGroup>
<Analyzer Include="..\packages\Microsoft.CodeAnalysis.VersionCheckAnalyzer.2.9.8\analyzers\dotnet\cs\Microsoft.CodeAnalysis.VersionCheckAnalyzer.resources.dll" />
<Analyzer Include="..\packages\Microsoft.CodeAnalysis.VersionCheckAnalyzer.2.9.8\analyzers\dotnet\Microsoft.CodeAnalysis.VersionCheckAnalyzer.dll" />
<Analyzer Include="..\packages\Microsoft.CodeQuality.Analyzers.2.9.8\analyzers\dotnet\cs\Humanizer.dll" />
<Analyzer Include="..\packages\Microsoft.CodeQuality.Analyzers.2.9.8\analyzers\dotnet\cs\Microsoft.CodeQuality.Analyzers.dll" />
<Analyzer Include="..\packages\Microsoft.CodeQuality.Analyzers.2.9.8\analyzers\dotnet\cs\Microsoft.CodeQuality.CSharp.Analyzers.dll" />
<Analyzer Include="..\packages\Microsoft.NetCore.Analyzers.2.9.8\analyzers\dotnet\cs\Microsoft.NetCore.Analyzers.dll" />
<Analyzer Include="..\packages\Microsoft.NetCore.Analyzers.2.9.8\analyzers\dotnet\cs\Microsoft.NetCore.CSharp.Analyzers.dll" />
<Analyzer Include="..\packages\Microsoft.NetFramework.Analyzers.2.9.8\analyzers\dotnet\cs\Microsoft.NetFramework.Analyzers.dll" />
<Analyzer Include="..\packages\Microsoft.NetFramework.Analyzers.2.9.8\analyzers\dotnet\cs\Microsoft.NetFramework.CSharp.Analyzers.dll" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\Microsoft.CodeAnalysis.VersionCheckAnalyzer.2.9.8\build\Microsoft.CodeAnalysis.VersionCheckAnalyzer.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.CodeAnalysis.VersionCheckAnalyzer.2.9.8\build\Microsoft.CodeAnalysis.VersionCheckAnalyzer.props'))" />
<Error Condition="!Exists('..\packages\Microsoft.CodeQuality.Analyzers.2.9.8\build\Microsoft.CodeQuality.Analyzers.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.CodeQuality.Analyzers.2.9.8\build\Microsoft.CodeQuality.Analyzers.props'))" />
<Error Condition="!Exists('..\packages\Microsoft.NetCore.Analyzers.2.9.8\build\Microsoft.NetCore.Analyzers.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.NetCore.Analyzers.2.9.8\build\Microsoft.NetCore.Analyzers.props'))" />
<Error Condition="!Exists('..\packages\Microsoft.NetFramework.Analyzers.2.9.8\build\Microsoft.NetFramework.Analyzers.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.NetFramework.Analyzers.2.9.8\build\Microsoft.NetFramework.Analyzers.props'))" />
<Error Condition="!Exists('..\packages\Microsoft.CodeAnalysis.FxCopAnalyzers.2.9.8\build\Microsoft.CodeAnalysis.FxCopAnalyzers.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.CodeAnalysis.FxCopAnalyzers.2.9.8\build\Microsoft.CodeAnalysis.FxCopAnalyzers.props'))" />
</Target>
</Project> </Project>

@ -0,0 +1,56 @@
namespace RadeonResetBugFixService
{
using System;
using System.Globalization;
using Microsoft.Win32;
static class RegistryHelper
{
private class RegistryValuePath
{
public string KeyName { get; }
public string ValueName { get; }
public RegistryValuePath(string keyName, string valueName)
{
this.KeyName = keyName;
this.ValueName = valueName;
}
}
private static RegistryValuePath PreshutdownOrderPath = new RegistryValuePath(@"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control", "PreshutdownOrder");
private static RegistryValuePath WaitToKillServiceTimeoutPath = new RegistryValuePath(@"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control", "WaitToKillServiceTimeout");
private static RegistryValuePath FastRebootPath = new RegistryValuePath(@"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Power", "HiberbootEnabled");
private static RegistryValuePath NoInteractiveServicesPath = new RegistryValuePath(@"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Windows", "NoInteractiveServices");
private static RegistryValuePath BasicDisplayStartTypePath = new RegistryValuePath(@"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\BasicDisplay", "Start");
private static T GetValue<T>(RegistryValuePath path, T defaultValue = default) => (T)Registry.GetValue(path.KeyName, path.ValueName, defaultValue);
private static void SetValue<T>(RegistryValuePath path, T value, RegistryValueKind valueKind) => Registry.SetValue(path.KeyName, path.ValueName, value, valueKind);
private static void SetValue(RegistryValuePath path, int value) => SetValue(path, value, RegistryValueKind.DWord);
private static void SetValue(RegistryValuePath path, string value) => SetValue(path, value, RegistryValueKind.String);
private static void SetValue(RegistryValuePath path, string[] value) => SetValue(path, value, RegistryValueKind.MultiString);
public static string[] GetPreshutdownOrder() => GetValue(PreshutdownOrderPath, Array.Empty<string>());
public static void SetPreshutdownOrder(string[] value) => SetValue(PreshutdownOrderPath, value);
public static void SetWaitToKillServiceTimeout(int milliseconds) => SetValue(WaitToKillServiceTimeoutPath, milliseconds.ToString(CultureInfo.InvariantCulture));
public static void SetFastRebootStatus(bool isEnabled) => SetValue(FastRebootPath, isEnabled ? 1 : 0);
public static void SetInteractiveServicesStatus(bool areInteractiveServicesAllowed) => SetValue(NoInteractiveServicesPath, areInteractiveServicesAllowed ? 0 : 1);
public static int GetBasicDisplayStartType() => GetValue(BasicDisplayStartTypePath, -1);
public static void SetBasicDisplayStartType(int startType) => SetValue(BasicDisplayStartTypePath, startType);
}
}

@ -20,57 +20,61 @@
if (this.ShouldStart(originalService)) if (this.ShouldStart(originalService))
{ {
var service = new ServiceController(originalService.ServiceName); using (var service = new ServiceController(originalService.ServiceName))
if (service.Status == ServiceControllerStatus.Running)
{ {
logger.Log($"{serviceDescription} is already running");
}
else
{
if (service.Status != ServiceControllerStatus.StartPending)
{
logger.Log($"Starting service {serviceDescription}");
service.Start();
logger.Log($"Initiated service start for");
}
logger.Log($"Waiting for service {serviceDescription} to start");
service.WaitForStatus(ServiceControllerStatus.Running, TimeSpan.FromSeconds(30));
if (service.Status == ServiceControllerStatus.Running) if (service.Status == ServiceControllerStatus.Running)
{ {
logger.Log($"Service is running"); logger.Log($"{serviceDescription} is already running");
} }
else else
{ {
logger.Log($"Failed; service state is {service.Status}"); if (service.Status != ServiceControllerStatus.StartPending)
{
logger.Log($"Starting service {serviceDescription}");
service.Start();
logger.Log($"Initiated service start for");
}
logger.Log($"Waiting for service {serviceDescription} to start");
service.WaitForStatus(ServiceControllerStatus.Running, TimeSpan.FromSeconds(30));
if (service.Status == ServiceControllerStatus.Running)
{
logger.Log($"Service is running");
}
else
{
logger.Log($"Failed; service state is {service.Status}");
}
} }
} }
} }
else if (this.ShouldStop(originalService)) else if (this.ShouldStop(originalService))
{ {
var service = new ServiceController(originalService.ServiceName); using (var service = new ServiceController(originalService.ServiceName))
if (service.Status == ServiceControllerStatus.Stopped)
{ {
logger.Log($"{serviceDescription} is already stopped");
}
else
{
if (service.Status != ServiceControllerStatus.StopPending)
{
logger.Log($"Stopping service {serviceDescription}");
service.Stop();
logger.Log($"Initiated service stop");
}
logger.Log($"Waiting for service {serviceDescription} to stop");
service.WaitForStatus(ServiceControllerStatus.Stopped, TimeSpan.FromSeconds(15));
if (service.Status == ServiceControllerStatus.Stopped) if (service.Status == ServiceControllerStatus.Stopped)
{ {
logger.Log($"Service is stopped"); logger.Log($"{serviceDescription} is already stopped");
} }
else else
{ {
logger.Log($"Failed; service state is {service.Status}"); if (service.Status != ServiceControllerStatus.StopPending)
{
logger.Log($"Stopping service {serviceDescription}");
service.Stop();
logger.Log($"Initiated service stop");
}
logger.Log($"Waiting for service {serviceDescription} to stop");
service.WaitForStatus(ServiceControllerStatus.Stopped, TimeSpan.FromSeconds(15));
if (service.Status == ServiceControllerStatus.Stopped)
{
logger.Log($"Service is stopped");
}
else
{
logger.Log($"Failed; service state is {service.Status}");
}
} }
} }
} }

@ -1,6 +1,4 @@
using RadeonResetBugFixService.Contracts; namespace RadeonResetBugFixService.Tasks
namespace RadeonResetBugFixService.Tasks
{ {
using Contracts; using Contracts;
using Devices; using Devices;

@ -1,7 +1,6 @@
namespace RadeonResetBugFixService.Tasks namespace RadeonResetBugFixService.Tasks
{ {
using System; using System;
using Microsoft.Win32;
using Contracts; using Contracts;
using Devices; using Devices;
@ -31,9 +30,9 @@
if (disabledStatus.HasValue && !disabledStatus.Value) if (disabledStatus.HasValue && !disabledStatus.Value)
{ {
logger.Log($"Device is enabled; disabling BasicDisplay service"); logger.Log($"Device is enabled; disabling BasicDisplay service");
var originalValue = Registry.GetValue(Constants.RegistryKeyBasicDisplay, "Start", -1); var originalValue = RegistryHelper.GetBasicDisplayStartType();
logger.Log($"Original start value {originalValue}"); logger.Log($"Original start value {originalValue}");
Registry.SetValue(Constants.RegistryKeyBasicDisplay, "Start", 4); RegistryHelper.SetBasicDisplayStartType(4);
} }
else else
{ {

@ -1,6 +1,5 @@
namespace RadeonResetBugFixService.Tasks namespace RadeonResetBugFixService.Tasks
{ {
using Microsoft.Win32;
using Contracts; using Contracts;
class EnableBasicDisplayStartupTask : ITask class EnableBasicDisplayStartupTask : ITask
@ -9,9 +8,9 @@
void ITask.Run(ILogger logger) void ITask.Run(ILogger logger)
{ {
var originalValue = Registry.GetValue(Constants.RegistryKeyBasicDisplay, "Start", -1); var originalValue = RegistryHelper.GetBasicDisplayStartType();
logger.Log($"Original start value {originalValue}"); logger.Log($"Original start value {originalValue}");
Registry.SetValue(Constants.RegistryKeyBasicDisplay, "Start", 3); RegistryHelper.SetBasicDisplayStartType(3);
} }
} }
} }

@ -1,9 +1,8 @@
namespace RadeonResetBugFixService.Tasks namespace RadeonResetBugFixService.Tasks
{ {
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using Contracts; using Contracts;
using Devices;
class FixMonitorTask : ITask class FixMonitorTask : ITask
{ {
@ -16,7 +15,7 @@
foreach (var display in ThirdParty.MonitorChanger.Display.GetDisplayList()) foreach (var display in ThirdParty.MonitorChanger.Display.GetDisplayList())
{ {
logger.Log($"Found display(ID='{display.DeviceID}' Key='{display.DeviceKey}', Name='{display.DeviceName}', String='{display.DeviceString}')"); logger.Log($"Found display(ID='{display.DeviceID}' Key='{display.DeviceKey}', Name='{display.DeviceName}', String='{display.DeviceString}')");
if (display.DeviceID.ToLowerInvariant().StartsWith(@"monitor\mhs062e")) if (display.DeviceID.StartsWith(@"Monitor\MHS062E", StringComparison.OrdinalIgnoreCase))
{ {
hypervDisplays.Add(display); hypervDisplays.Add(display);
} }

@ -1,14 +1,15 @@
using System.ServiceProcess; namespace RadeonResetBugFixService.Tasks
namespace RadeonResetBugFixService.Tasks
{ {
using System;
using System.ServiceProcess;
class StopAudioServiceTask : AbstractServiceTask class StopAudioServiceTask : AbstractServiceTask
{ {
public override string TaskName => "Stopping audio service"; public override string TaskName => "Stopping audio service";
protected override bool ShouldStop(ServiceController serviceInfo) protected override bool ShouldStop(ServiceController serviceInfo)
{ {
return serviceInfo.ServiceName.ToLowerInvariant() == "audiosrv"; return serviceInfo.ServiceName.Equals("audiosrv", StringComparison.OrdinalIgnoreCase);
} }
} }
} }

@ -1,8 +1,9 @@
namespace RadeonResetBugFixService.ThirdParty.DisableDevice // This file isn't generated, but this comment is necessary to exclude it from StyleCop analysis.
// <auto-generated/>
// Code taken from https://stackoverflow.com/a/1610140
// Code for obtaining device status is mine
namespace RadeonResetBugFixService.ThirdParty.DisableDevice
{ {
// Code taken from https://stackoverflow.com/a/1610140
// Code for obtaining device status is mine
using System; using System;
using System.Text; using System.Text;
using System.Collections.Generic; using System.Collections.Generic;

@ -1,6 +1,8 @@
namespace RadeonResetBugFixService.ThirdParty.MonitorChanger // This file isn't generated, but this comment is necessary to exclude it from StyleCop analysis.
// <auto-generated/>
// Code taken from https://github.com/Grunge/setDisplayRes
namespace RadeonResetBugFixService.ThirdParty.MonitorChanger
{ {
// Code taken from https://github.com/Grunge/setDisplayRes
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;

@ -92,7 +92,7 @@
} }
} }
public static void StartService(string serviceName, Type serviceType) public static void StartService(string serviceName)
{ {
if (!IsInstalled(serviceName)) return; if (!IsInstalled(serviceName)) return;
@ -101,20 +101,21 @@
if (controller.Status != ServiceControllerStatus.Running) if (controller.Status != ServiceControllerStatus.Running)
{ {
controller.Start(); controller.Start();
controller.WaitForStatus(ServiceControllerStatus.Running, TimeSpan.FromMinutes(6)); controller.WaitForStatus(ServiceControllerStatus.Running, Constants.ServiceTimeout);
} }
} }
} }
public static void StopService(string serviceName, Type serviceType) public static void StopService(string serviceName)
{ {
if (!IsInstalled(serviceName)) return; if (!IsInstalled(serviceName)) return;
using (ServiceController controller = new ServiceController(serviceName)) using (ServiceController controller = new ServiceController(serviceName))
{ {
if (controller.Status != ServiceControllerStatus.Stopped) if (controller.Status != ServiceControllerStatus.Stopped)
{ {
controller.Stop(); controller.Stop();
controller.WaitForStatus(ServiceControllerStatus.Stopped, TimeSpan.FromMinutes(6)); controller.WaitForStatus(ServiceControllerStatus.Stopped, Constants.ServiceTimeout);
} }
} }
} }

@ -1,6 +1,8 @@
namespace RadeonResetBugFixService.ThirdParty.ServicePreshutdownHelpers // This file isn't generated, but this comment is necessary to exclude it from StyleCop analysis.
// <auto-generated/>
// Code taken from https://social.msdn.microsoft.com/Forums/vstudio/en-US/d14549e2-d0bc-47fb-bb01-7e0ac57fa712/keep-windows-service-alive-for-more-then-3-minutes-when-system-shut-down
namespace RadeonResetBugFixService.ThirdParty.ServicePreshutdownHelpers
{ {
// Code taken from https://social.msdn.microsoft.com/Forums/vstudio/en-US/d14549e2-d0bc-47fb-bb01-7e0ac57fa712/keep-windows-service-alive-for-more-then-3-minutes-when-system-shut-down
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.CodeAnalysis.FxCopAnalyzers" version="2.9.8" targetFramework="net472" developmentDependency="true" />
<package id="Microsoft.CodeAnalysis.VersionCheckAnalyzer" version="2.9.8" targetFramework="net472" developmentDependency="true" />
<package id="Microsoft.CodeQuality.Analyzers" version="2.9.8" targetFramework="net472" developmentDependency="true" />
<package id="Microsoft.NetCore.Analyzers" version="2.9.8" targetFramework="net472" developmentDependency="true" />
<package id="Microsoft.NetFramework.Analyzers" version="2.9.8" targetFramework="net472" developmentDependency="true" />
</packages>
Loading…
Cancel
Save