From 3bcbf00a0ff529046027213944a6e094af68269c Mon Sep 17 00:00:00 2001
From: Inga Lovinde <52715130+inga-lovinde@users.noreply.github.com>
Date: Sun, 1 Dec 2019 13:30:50 +0300
Subject: [PATCH] A bunch of more workarounds/hacks, install experience
improved, FixMonitorTask implemented
---
.../Devices/DeviceHelper.cs | 33 +-
RadeonResetBugFixService/MainHandler.cs | 11 +-
RadeonResetBugFixService/Program.cs | 18 +-
RadeonResetBugFixService/ProjectInstaller.cs | 18 +-
.../RadeonResetBugFixService.cs | 23 +-
.../RadeonResetBugFixService.csproj | 2 +
.../Tasks/AbstractDevicesTask.cs | 24 +-
.../Tasks/FixMonitorTask.cs | 38 ++
.../ThirdParty/MonitorChanger.cs | 382 ++++++++++++++++++
.../ThirdParty/ServiceHelpers.cs | 4 +-
10 files changed, 537 insertions(+), 16 deletions(-)
create mode 100644 RadeonResetBugFixService/Tasks/FixMonitorTask.cs
create mode 100644 RadeonResetBugFixService/ThirdParty/MonitorChanger.cs
diff --git a/RadeonResetBugFixService/Devices/DeviceHelper.cs b/RadeonResetBugFixService/Devices/DeviceHelper.cs
index 73877b3..92ae405 100644
--- a/RadeonResetBugFixService/Devices/DeviceHelper.cs
+++ b/RadeonResetBugFixService/Devices/DeviceHelper.cs
@@ -3,6 +3,8 @@
using System;
using System.Collections.Generic;
using System.Management;
+ using System.Threading;
+ using System.Threading.Tasks;
using Contracts;
class DeviceHelper
@@ -72,17 +74,44 @@
public static void DisableDevice(DeviceInfo deviceInfo)
{
- ThirdParty.DisableDevice.DeviceHelper.SetDeviceEnabled(deviceInfo.ClassGuid, deviceInfo.DeviceId, false);
+ RunWithTimeout(
+ () => ThirdParty.DisableDevice.DeviceHelper.SetDeviceEnabled(deviceInfo.ClassGuid, deviceInfo.DeviceId, false),
+ TimeSpan.FromSeconds(50));
}
public static void EnableDevice(DeviceInfo deviceInfo)
{
- ThirdParty.DisableDevice.DeviceHelper.SetDeviceEnabled(deviceInfo.ClassGuid, deviceInfo.DeviceId, true);
+ RunWithTimeout(
+ () => ThirdParty.DisableDevice.DeviceHelper.SetDeviceEnabled(deviceInfo.ClassGuid, deviceInfo.DeviceId, true),
+ TimeSpan.FromSeconds(50));
}
public static bool? IsDeviceCurrentlyDisabled(DeviceInfo deviceInfo)
{
return ThirdParty.DisableDevice.DeviceHelper.IsDeviceDisabled(deviceInfo.ClassGuid, deviceInfo.DeviceId);
}
+
+ private static void RunWithTimeout(Action action, TimeSpan timeout)
+ {
+ Exception localException = null;
+ Task.WaitAny(
+ Task.Run(() =>
+ {
+ try
+ {
+ action();
+ }
+ catch (Exception e)
+ {
+ localException = new Exception("Exception from action", e);
+ }
+ }),
+ Task.Delay(timeout));
+
+ if (localException != null)
+ {
+ throw localException;
+ }
+ }
}
}
diff --git a/RadeonResetBugFixService/MainHandler.cs b/RadeonResetBugFixService/MainHandler.cs
index 3c1cae7..6bbb473 100644
--- a/RadeonResetBugFixService/MainHandler.cs
+++ b/RadeonResetBugFixService/MainHandler.cs
@@ -26,12 +26,13 @@
$"radeonfix_{date:yyyyMMdd}_{date:HHmmss}.log");
}
- public void HandleStartup()
+ public void HandleStartup(string reason)
{
using (var fileLogger = new FileLogger(this.LogFilename))
{
using (ILogger logger = new TaskLoggerWrapper(fileLogger, "Startup"))
{
+ logger.Log($"Reason: {reason}");
try
{
lock (this.Mutex)
@@ -43,6 +44,10 @@
new SleepTask(TimeSpan.FromSeconds(20)),
new DisableVirtualVideoTask(this.StartupDevicesStatus),
new EnableAmdVideoTask(this.StartupDevicesStatus),
+ new SleepTask(TimeSpan.FromSeconds(40)),
+ new FixMonitorTask(),
+ new DisableVirtualVideoTask(this.StartupDevicesStatus),
+ new FixMonitorTask(),
});
}
}
@@ -54,12 +59,13 @@
}
}
- public void HandleShutdown()
+ public void HandleShutdown(string reason)
{
using (var fileLogger = new FileLogger(this.LogFilename))
{
using (ILogger logger = new TaskLoggerWrapper(fileLogger, "Shutdown"))
{
+ logger.Log($"Reason: {reason}");
try
{
lock (this.Mutex)
@@ -72,6 +78,7 @@
new DisableAmdVideoTask(this.ShutdownDevicesStatus),
new EnableVirtualVideoTask(this.ShutdownDevicesStatus),
new LastResortDevicesRestoreTask(this.StartupDevicesStatus),
+ new LastResortDevicesRestoreTask(this.StartupDevicesStatus), // just in case
});
}
}
diff --git a/RadeonResetBugFixService/Program.cs b/RadeonResetBugFixService/Program.cs
index 9a5516b..72175df 100644
--- a/RadeonResetBugFixService/Program.cs
+++ b/RadeonResetBugFixService/Program.cs
@@ -1,5 +1,6 @@
namespace RadeonResetBugFixService
{
+ using Microsoft.Win32;
using System;
using System.Security.Principal;
using System.ServiceProcess;
@@ -87,24 +88,37 @@
private static void DoInstall()
{
+ 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", "300000", RegistryValueKind.String);
+
+ // Disable fast restart
+ Registry.SetValue(@"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Power", "HiberbootEnabled", 0, RegistryValueKind.DWord);
+
+ Console.WriteLine("Installing service...");
ServiceHelpers.InstallService(nameof(RadeonResetBugFixService), typeof(RadeonResetBugFixService));
+ Console.WriteLine("Starting service...");
ServiceHelpers.StartService(nameof(RadeonResetBugFixService), typeof(RadeonResetBugFixService));
+ Console.WriteLine("Started service");
}
private static void DoUninstall()
{
+ Console.WriteLine("Stopping service...");
ServiceHelpers.StopService(nameof(RadeonResetBugFixService), typeof(RadeonResetBugFixService));
+ Console.WriteLine("Uninstalling service...");
ServiceHelpers.UninstallService(nameof(RadeonResetBugFixService), typeof(RadeonResetBugFixService));
+ Console.WriteLine("Uninstalled");
}
private static void DoStartup()
{
- new MainHandler().HandleStartup();
+ new MainHandler().HandleStartup("Program.DoStartup");
}
private static void DoShutdown()
{
- new MainHandler().HandleShutdown();
+ new MainHandler().HandleShutdown("Program.DoShutdown");
}
// Code taken from https://stackoverflow.com/a/2679654
diff --git a/RadeonResetBugFixService/ProjectInstaller.cs b/RadeonResetBugFixService/ProjectInstaller.cs
index d48a816..8b72a72 100644
--- a/RadeonResetBugFixService/ProjectInstaller.cs
+++ b/RadeonResetBugFixService/ProjectInstaller.cs
@@ -4,6 +4,7 @@ using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration.Install;
using System.Linq;
+using System.Management;
using System.Threading.Tasks;
namespace RadeonResetBugFixService
@@ -18,7 +19,22 @@ namespace RadeonResetBugFixService
private void serviceInstaller1_AfterInstall(object sender, InstallEventArgs e)
{
-
+ ManagementObject wmiService = null;
+ ManagementBaseObject InParam = null;
+ try
+ {
+ wmiService = new ManagementObject($"Win32_Service.Name='{this.serviceInstaller1.ServiceName}'");
+ InParam = wmiService.GetMethodParameters("Change");
+ InParam["DesktopInteract"] = true;
+ wmiService.InvokeMethod("Change", InParam, null);
+ }
+ finally
+ {
+ if (InParam != null)
+ InParam.Dispose();
+ if (wmiService != null)
+ wmiService.Dispose();
+ }
}
private void serviceProcessInstaller1_AfterInstall(object sender, InstallEventArgs e)
diff --git a/RadeonResetBugFixService/RadeonResetBugFixService.cs b/RadeonResetBugFixService/RadeonResetBugFixService.cs
index 6740ba3..78b6d51 100644
--- a/RadeonResetBugFixService/RadeonResetBugFixService.cs
+++ b/RadeonResetBugFixService/RadeonResetBugFixService.cs
@@ -1,4 +1,5 @@
-using System;
+using Microsoft.Win32;
+using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
@@ -21,17 +22,31 @@ namespace RadeonResetBugFixService
protected override void OnShutdown()
{
- this.Handler.HandleShutdown();
+ SystemEvents.SessionEnding -= this.OnSessionEnding;
+ this.RequestAdditionalTime(300000);
+ this.Handler.HandleShutdown("ServiceBase.OnShutdown");
}
protected override void OnStart(string[] args)
{
- this.Handler.HandleStartup();
+ this.Handler.HandleStartup("ServiceBase.OnStart");
+ this.RequestAdditionalTime(300000);
+ SystemEvents.SessionEnding += this.OnSessionEnding;
}
protected override void OnStop()
{
- this.Handler.HandleShutdown();
+ SystemEvents.SessionEnding -= this.OnSessionEnding;
+ this.RequestAdditionalTime(300000);
+ this.Handler.HandleShutdown("ServiceBase.OnStop");
+ }
+
+ private void OnSessionEnding(object sender, SessionEndingEventArgs args)
+ {
+ if (args.Reason == SessionEndReasons.SystemShutdown)
+ {
+ this.Handler.HandleShutdown("SystemEvents.SessionEnding");
+ }
}
}
}
diff --git a/RadeonResetBugFixService/RadeonResetBugFixService.csproj b/RadeonResetBugFixService/RadeonResetBugFixService.csproj
index 467bfd0..2bb30f9 100644
--- a/RadeonResetBugFixService/RadeonResetBugFixService.csproj
+++ b/RadeonResetBugFixService/RadeonResetBugFixService.csproj
@@ -72,8 +72,10 @@
+
+
diff --git a/RadeonResetBugFixService/Tasks/AbstractDevicesTask.cs b/RadeonResetBugFixService/Tasks/AbstractDevicesTask.cs
index c33d4af..230e86b 100644
--- a/RadeonResetBugFixService/Tasks/AbstractDevicesTask.cs
+++ b/RadeonResetBugFixService/Tasks/AbstractDevicesTask.cs
@@ -39,6 +39,11 @@
}
else
{
+ if (device.ErrorCode != 0)
+ {
+ logger.LogError($"Device is in error state: {device.ErrorCode}");
+ }
+
logger.Log($"Disabling {device.Description}");
DeviceHelper.DisableDevice(device);
logger.Log($"Disabled {device.Description}");
@@ -51,6 +56,11 @@
if (!device.IsDisabled)
{
logger.Log($"{device.Description} is already enabled");
+
+ if (device.ErrorCode != 0)
+ {
+ logger.LogError($"Device is in error state: {device.ErrorCode}");
+ }
}
else
{
@@ -65,13 +75,17 @@
{
if (this.ShouldDisable(device))
{
- if (!device.IsDisabled)
+ if (device.IsDisabled)
{
- logger.LogError($"{device.Description} is enabled but should be disabled");
+ logger.Log($"Successfully checked {device.Description} status");
+ }
+ else if (device.ErrorCode != 0)
+ {
+ logger.LogError($"Device is in error state: {device.ErrorCode}");
}
else
{
- logger.Log($"Successfully checked {device.Description} status");
+ logger.LogError($"{device.Description} is enabled but should be disabled");
}
}
else if (this.ShouldEnable(device))
@@ -80,6 +94,10 @@
{
logger.Log($"{device.Description} is disabled but should be enabled");
}
+ else if (device.ErrorCode != 0)
+ {
+ logger.LogError($"Device is in error state: {device.ErrorCode}");
+ }
else
{
logger.Log($"Successfully checked {device.Description} status");
diff --git a/RadeonResetBugFixService/Tasks/FixMonitorTask.cs b/RadeonResetBugFixService/Tasks/FixMonitorTask.cs
new file mode 100644
index 0000000..01a6517
--- /dev/null
+++ b/RadeonResetBugFixService/Tasks/FixMonitorTask.cs
@@ -0,0 +1,38 @@
+namespace RadeonResetBugFixService.Tasks
+{
+ using System.Collections.Generic;
+ using System.Linq;
+ using Contracts;
+ using Devices;
+
+ class FixMonitorTask : ITask
+ {
+ public string TaskName => "Fixing monitor";
+
+ public void Run(ILogger logger)
+ {
+ var hypervDisplays = new List();
+ var realDisplays = new List();
+ foreach (var display in ThirdParty.MonitorChanger.Display.GetDisplayList())
+ {
+ logger.Log($"Found display(ID='{display.DeviceID}' Key='{display.DeviceKey}', Name='{display.DeviceName}', String='{display.DeviceString}')");
+ if (display.DeviceID.ToLowerInvariant().StartsWith(@"monitor\mhs062e"))
+ {
+ hypervDisplays.Add(display);
+ }
+ else
+ {
+ realDisplays.Add(display);
+ }
+ }
+
+ logger.Log($"Found {hypervDisplays.Count} virtual displays and {realDisplays.Count} real displays");
+ if (hypervDisplays.Count > 0 && realDisplays.Count > 0)
+ {
+ var newPrimaryDisplay = realDisplays[0];
+ logger.Log($"Setting default display to {newPrimaryDisplay.DeviceID}");
+ ThirdParty.MonitorChanger.Display.SetAsPrimaryMonitor(newPrimaryDisplay);
+ }
+ }
+ }
+}
diff --git a/RadeonResetBugFixService/ThirdParty/MonitorChanger.cs b/RadeonResetBugFixService/ThirdParty/MonitorChanger.cs
new file mode 100644
index 0000000..10d92ec
--- /dev/null
+++ b/RadeonResetBugFixService/ThirdParty/MonitorChanger.cs
@@ -0,0 +1,382 @@
+namespace RadeonResetBugFixService.ThirdParty.MonitorChanger
+{
+ // Code taken from https://github.com/Grunge/setDisplayRes
+ using System;
+ using System.Collections.Generic;
+ using System.Runtime.InteropServices;
+
+ // Encapsulates access to the PInvoke functions
+ public class Display
+ {
+ public static List GetDisplayList(bool RetrieveMonitorname = false)
+ {
+ //todo: EDD_GET_DEVICE_INTERFACE_NAME
+ //const int EDD_GET_DEVICE_INTERFACE_NAME = 0x1;
+
+ List displays = new List();
+ DISPLAY_DEVICE d = new DISPLAY_DEVICE();
+ d.cb = Marshal.SizeOf(d);
+ try
+ {
+ for (uint id = 0; NativeMethods.EnumDisplayDevices(null, id, ref d, 0); id++)
+ {
+ if (d.StateFlags.HasFlag(DisplayDeviceStateFlags.AttachedToDesktop))
+ {
+ //call again to get the monitor name (not only the graka name).
+ DISPLAY_DEVICE devWithName = new DISPLAY_DEVICE();
+ devWithName.cb = Marshal.SizeOf(devWithName);
+
+ NativeMethods.EnumDisplayDevices(d.DeviceName, 0, ref devWithName, 0);
+ //overwrite device string and id, keep the rest!
+ d.DeviceString = devWithName.DeviceString;
+ d.DeviceID = devWithName.DeviceID;
+
+ displays.Add(d);
+ }//if is display
+ }//for
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine(String.Format("{0}", ex.ToString()));
+ }
+
+ return displays;
+ }
+
+
+
+
+
+ // Return a list of all possible display types for this computer
+ public static List GetDisplaySettings(string strDevName)
+ {
+ List modes = new List();
+ DevMode devmode = DevMode;
+
+ int counter = 0;
+ int returnValue = 1;
+
+ // A return value of zero indicates that no more settings are available
+ while (returnValue != 0)
+ {
+ returnValue = GetSettings(strDevName, ref devmode, counter++);
+
+ modes.Add(devmode);
+ }
+
+ return modes;
+ }
+
+ // Return the current display setting
+ public int GetCurrentSettings(string strDevName, ref DevMode devmode)
+ {
+ return GetSettings(strDevName, ref devmode, NativeMethods.ENUM_CURRENT_SETTINGS);
+ }
+
+
+
+ //todo: CDS_UPDATEREGISTRY
+
+ // Change the settings to the values of the DEVMODE passed
+ public static string ChangeSettings(DISPLAY_DEVICE a_dev, DevMode devmode, bool bSetPrimary)
+ {
+ string errorMessage = "";
+ ChangeDisplaySettingsFlags flags = new ChangeDisplaySettingsFlags();
+ flags = ChangeDisplaySettingsFlags.CDS_UPDATEREGISTRY | ChangeDisplaySettingsFlags.CDS_GLOBAL;
+
+ ReturnCodes iRet = NativeMethods.ChangeDisplaySettingsEx(a_dev.DeviceName, ref devmode, IntPtr.Zero, flags, IntPtr.Zero);
+
+ //same again, but with PRIMARY
+ if (bSetPrimary && iRet == ReturnCodes.DISP_CHANGE_SUCCESSFUL)
+ {
+ SetAsPrimaryMonitor(a_dev);
+ }//if primary
+
+ switch (iRet)
+ {
+ case ReturnCodes.DISP_CHANGE_SUCCESSFUL:
+ break;
+ case ReturnCodes.DISP_CHANGE_RESTART:
+ errorMessage = "Please restart your system";
+ break;
+ case ReturnCodes.DISP_CHANGE_FAILED:
+ errorMessage = "ChangeDisplaySettigns API failed";
+ break;
+ case ReturnCodes.DISP_CHANGE_BADDUALVIEW:
+ errorMessage = "The settings change was unsuccessful because system is DualView capable.";
+ break;
+ case ReturnCodes.DISP_CHANGE_BADFLAGS:
+ errorMessage = "An invalid set of flags was passed in.";
+ break;
+ case ReturnCodes.DISP_CHANGE_BADPARAM:
+ errorMessage = "An invalid parameter was passed in. This can include an invalid flag or combination of flags.";
+ break;
+ case ReturnCodes.DISP_CHANGE_NOTUPDATED:
+ errorMessage = "Unable to write settings to the registry.";
+ break;
+ default:
+ errorMessage = "Unknown return value from ChangeDisplaySettings API";
+ break;
+ }
+ return errorMessage;
+ }
+
+ public static void SetAsPrimaryMonitor(DISPLAY_DEVICE a_dev)
+ {
+ var deviceMode = new DevMode();
+ NativeMethods.EnumDisplaySettings(a_dev.DeviceName, -1, ref deviceMode);
+ var offsetx = deviceMode.dmPositionX;
+ var offsety = deviceMode.dmPositionY;
+ deviceMode.dmPositionX = 0;
+ deviceMode.dmPositionY = 0;
+
+ NativeMethods.ChangeDisplaySettingsEx(
+ a_dev.DeviceName,
+ ref deviceMode,
+ (IntPtr)null,
+ (ChangeDisplaySettingsFlags.CDS_SET_PRIMARY | ChangeDisplaySettingsFlags.CDS_UPDATEREGISTRY | ChangeDisplaySettingsFlags.CDS_NORESET),
+ IntPtr.Zero);
+
+ var device = new DISPLAY_DEVICE();
+ device.cb = Marshal.SizeOf(device);
+
+ // Update other devices
+ for (uint otherid = 0; NativeMethods.EnumDisplayDevices(null, otherid, ref device, 0); otherid++)
+ {
+ if (device.StateFlags.HasFlag(DisplayDeviceStateFlags.AttachedToDesktop) && device.DeviceID != a_dev.DeviceID)
+ {
+ device.cb = Marshal.SizeOf(device);
+ var otherDeviceMode = new DevMode();
+
+ NativeMethods.EnumDisplaySettings(device.DeviceName, -1, ref otherDeviceMode);
+
+ otherDeviceMode.dmPositionX -= offsetx;
+ otherDeviceMode.dmPositionY -= offsety;
+
+ NativeMethods.ChangeDisplaySettingsEx(
+ device.DeviceName,
+ ref otherDeviceMode,
+ (IntPtr)null,
+ (ChangeDisplaySettingsFlags.CDS_UPDATEREGISTRY | ChangeDisplaySettingsFlags.CDS_NORESET),
+ IntPtr.Zero);
+
+ }
+
+ device.cb = Marshal.SizeOf(device);
+ }
+
+ // Apply settings
+ NativeMethods.ChangeDisplaySettingsEx(null, IntPtr.Zero, (IntPtr)null, ChangeDisplaySettingsFlags.CDS_NONE, (IntPtr)null);
+ }//set as primary()
+
+ // Return a properly configured DEVMODE
+ public static DevMode DevMode
+ {
+ get
+ {
+ DevMode devmode = new DevMode();
+ devmode.dmDeviceName = new String(new char[32]);
+ devmode.dmFormName = new String(new char[32]);
+ devmode.dmSize = (short)Marshal.SizeOf(devmode);
+ return devmode;
+ }
+ }
+
+ // call the external function inthe Win32 API
+ private static int GetSettings(string strDevName, ref DevMode devmode, int iModeNum)
+ {
+ // helper to wrap EnumDisplaySettings Win32 API
+ return NativeMethods.EnumDisplaySettings(strDevName, iModeNum, ref devmode);
+ }
+ }
+
+
+ // Encapsulate the magic numbers for the return value in an enumeration
+ public enum ReturnCodes : int
+ {
+ DISP_CHANGE_SUCCESSFUL = 0,
+ DISP_CHANGE_BADDUALVIEW = -6,
+ DISP_CHANGE_BADFLAGS = -4,
+ DISP_CHANGE_BADMODE = -2,
+ DISP_CHANGE_BADPARAM = -5,
+ DISP_CHANGE_FAILED = -1,
+ DISP_CHANGE_NOTUPDATED = -3,
+ DISP_CHANGE_RESTART = 1
+ }
+
+ // To see how the DEVMODE struct was translated from the unmanaged to the managed see the Task 2 Declarations section
+
+ // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/prntspol_8nle.asp
+ [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
+ public struct DevMode
+ {
+ // The MarshallAs attribute is covered in the Background section of the article
+ [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
+ public string dmDeviceName;
+
+ public short dmSpecVersion;
+ public short dmDriverVersion;
+ public short dmSize;
+ public short dmDriverExtra;
+ public int dmFields;
+ public int dmPositionX;
+ public int dmPositionY;
+ public int dmDisplayOrientation;
+ public int dmDisplayFixedOutput;
+ public short dmColor;
+ public short dmDuplex;
+ public short dmYResolution;
+ public short dmTTOption;
+ public short dmCollate;
+
+ [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
+ public string dmFormName;
+
+ public short dmLogPixels;
+ public short dmBitsPerPel;
+ public int dmPelsWidth;
+ public int dmPelsHeight;
+ public int dmDisplayFlags;
+ public int dmDisplayFrequency;
+ public int dmICMMethod;
+ public int dmICMIntent;
+ public int dmMediaType;
+ public int dmDitherType;
+ public int dmReserved1;
+ public int dmReserved2;
+ public int dmPanningWidth;
+ public int dmPanningHeight;
+
+ public override string ToString()
+ {
+ return dmPelsWidth.ToString() + " x " + dmPelsHeight.ToString();
+ }
+
+
+ public string[] GetInfoArray()
+ {
+ string[] items = new string[5];
+
+ items[0] = dmDeviceName;
+ items[1] = dmPelsWidth.ToString();
+ items[2] = dmPelsHeight.ToString();
+ items[3] = dmDisplayFrequency.ToString();
+ items[4] = dmBitsPerPel.ToString();
+
+ return items;
+ }
+ }
+
+
+ //Display Listening
+ [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
+ public struct DISPLAY_DEVICE
+ {
+ [MarshalAs(UnmanagedType.U4)]
+ public int cb;
+ [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
+ public string DeviceName;
+ [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
+ public string DeviceString;
+ [MarshalAs(UnmanagedType.U4)]
+ public DisplayDeviceStateFlags StateFlags;
+ [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
+ public string DeviceID;
+ [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
+ public string DeviceKey;
+ }
+
+ [Flags()]
+ public enum DEVMODE_Flags : int
+ {
+ DM_BITSPERPEL = 0x40000,
+ DM_DISPLAYFLAGS = 0x200000,
+ DM_DISPLAYFREQUENCY = 0x400000,
+ DM_PELSHEIGHT = 0x100000,
+ DM_PELSWIDTH = 0x80000,
+ DM_POSITION = 0x20
+ }
+
+ [Flags()]
+ public enum DisplayDeviceStateFlags : int
+ {
+ /// The device is part of the desktop.
+ AttachedToDesktop = 0x1,
+ MultiDriver = 0x2,
+ /// The device is part of the desktop.
+ PrimaryDevice = 0x4,
+ /// Represents a pseudo device used to mirror application drawing for remoting or other purposes.
+ MirroringDriver = 0x8,
+ /// The device is VGA compatible.
+ VGACompatible = 0x10,
+ /// The device is removable; it cannot be the primary display.
+ Removable = 0x20,
+ /// The device has more display modes than its output devices support.
+ ModesPruned = 0x8000000,
+ Remote = 0x4000000,
+ Disconnect = 0x2000000
+ }
+
+ [Flags()]
+ public enum ChangeDisplaySettingsFlags : uint
+ {
+ CDS_NONE = 0,
+ CDS_UPDATEREGISTRY = 0x00000001,
+ CDS_TEST = 0x00000002,
+ CDS_FULLSCREEN = 0x00000004,
+ CDS_GLOBAL = 0x00000008,
+ CDS_SET_PRIMARY = 0x00000010,
+ CDS_VIDEOPARAMETERS = 0x00000020,
+ CDS_ENABLE_UNSAFE_MODES = 0x00000100,
+ CDS_DISABLE_UNSAFE_MODES = 0x00000200,
+ CDS_RESET = 0x40000000,
+ CDS_RESET_EX = 0x20000000,
+ CDS_NORESET = 0x10000000
+ }
+
+ [Flags()]
+ public enum ChangeDisplayConfigFlags : uint
+ {
+ SDC_TOPOLOGY_INTERNAL = 0x00000001,
+ SDC_TOPOLOGY_CLONE = 0x00000002,
+ SDC_TOPOLOGY_EXTEND = 0x00000004,
+ SDC_TOPOLOGY_EXTERNAL = 0x00000008,
+ SDC_APPLY = 0x00000080,
+ }
+
+ class NativeMethods
+ {
+ // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/devcons_84oj.asp
+ [DllImport("user32.dll", CharSet = CharSet.Ansi)]
+ public static extern int EnumDisplaySettings(string lpszDeviceName, int iModeNum, ref DevMode lpDevMode);
+
+ // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/devcons_7gz7.asp
+ [DllImport("user32.dll", CharSet = CharSet.Ansi)] //CallingConvention = CallingConvention.Cdecl
+ public static extern ReturnCodes ChangeDisplaySettingsEx(string lpszDeviceName, ref DevMode lpDevMode, IntPtr hwnd, ChangeDisplaySettingsFlags dwFlags, IntPtr lParam);
+
+ [DllImport("user32.dll")]
+ public static extern int ChangeDisplaySettingsEx(int lpszDeviceName, int lpDevMode, int hwnd, int dwFlags, int lParam);
+
+
+ [DllImport("user32.dll")]
+ // A signature for ChangeDisplaySettingsEx with a DEVMODE struct as the second parameter won't allow you to pass in IntPtr.Zero, so create an overload
+ public static extern int ChangeDisplaySettingsEx(string lpszDeviceName, IntPtr lpDevMode, IntPtr hwnd, ChangeDisplaySettingsFlags dwflags, IntPtr lParam);
+
+
+
+
+
+ [DllImport("user32.dll", CharSet = CharSet.Ansi)]
+ public static extern ReturnCodes ChangeDisplaySettings(ref DevMode lpDevMode, int dwFlags);
+
+ [DllImport("user32.dll")]
+ public static extern bool EnumDisplayDevices(string lpDevice, uint iDevNum, ref DISPLAY_DEVICE lpDisplayDevice, uint dwFlags);
+
+
+ [DllImport("user32.dll", CharSet = CharSet.Unicode)]
+ public static extern long SetDisplayConfig(uint numPathArrayElements, IntPtr pathArray, uint numModeArrayElements, IntPtr modeArray, ChangeDisplayConfigFlags flags);
+
+
+ public const int ENUM_CURRENT_SETTINGS = -1;
+ }
+}
diff --git a/RadeonResetBugFixService/ThirdParty/ServiceHelpers.cs b/RadeonResetBugFixService/ThirdParty/ServiceHelpers.cs
index 2997913..f9c78b7 100644
--- a/RadeonResetBugFixService/ThirdParty/ServiceHelpers.cs
+++ b/RadeonResetBugFixService/ThirdParty/ServiceHelpers.cs
@@ -101,7 +101,7 @@
if (controller.Status != ServiceControllerStatus.Running)
{
controller.Start();
- controller.WaitForStatus(ServiceControllerStatus.Running, TimeSpan.FromSeconds(10));
+ controller.WaitForStatus(ServiceControllerStatus.Running, TimeSpan.FromMinutes(6));
}
}
}
@@ -114,7 +114,7 @@
if (controller.Status != ServiceControllerStatus.Stopped)
{
controller.Stop();
- controller.WaitForStatus(ServiceControllerStatus.Stopped, TimeSpan.FromSeconds(10));
+ controller.WaitForStatus(ServiceControllerStatus.Stopped, TimeSpan.FromMinutes(6));
}
}
}