A bunch of more workarounds/hacks, install experience improved, FixMonitorTask implemented

master
Inga 🏳‍🌈 5 years ago
parent 8bb6b7289e
commit 3bcbf00a0f
  1. 33
      RadeonResetBugFixService/Devices/DeviceHelper.cs
  2. 11
      RadeonResetBugFixService/MainHandler.cs
  3. 18
      RadeonResetBugFixService/Program.cs
  4. 18
      RadeonResetBugFixService/ProjectInstaller.cs
  5. 23
      RadeonResetBugFixService/RadeonResetBugFixService.cs
  6. 2
      RadeonResetBugFixService/RadeonResetBugFixService.csproj
  7. 24
      RadeonResetBugFixService/Tasks/AbstractDevicesTask.cs
  8. 38
      RadeonResetBugFixService/Tasks/FixMonitorTask.cs
  9. 382
      RadeonResetBugFixService/ThirdParty/MonitorChanger.cs
  10. 4
      RadeonResetBugFixService/ThirdParty/ServiceHelpers.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;
}
}
}
}

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

@ -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

@ -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)

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

@ -72,8 +72,10 @@
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Logging\TaskLoggerWrapper.cs" />
<Compile Include="Tasks\FixMonitorTask.cs" />
<Compile Include="Tasks\LastResortDevicesRestoreTask.cs" />
<Compile Include="Tasks\SleepTask.cs" />
<Compile Include="ThirdParty\MonitorChanger.cs" />
<Compile Include="ThirdParty\ServiceHelpers.cs" />
<Compile Include="TasksProcessor.cs" />
<Compile Include="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");

@ -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<ThirdParty.MonitorChanger.DISPLAY_DEVICE>();
var realDisplays = new List<ThirdParty.MonitorChanger.DISPLAY_DEVICE>();
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);
}
}
}
}

@ -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<DISPLAY_DEVICE> GetDisplayList(bool RetrieveMonitorname = false)
{
//todo: EDD_GET_DEVICE_INTERFACE_NAME
//const int EDD_GET_DEVICE_INTERFACE_NAME = 0x1;
List<DISPLAY_DEVICE> displays = new List<DISPLAY_DEVICE>();
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<DevMode> GetDisplaySettings(string strDevName)
{
List<DevMode> modes = new List<DevMode>();
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
{
/// <summary>The device is part of the desktop.</summary>
AttachedToDesktop = 0x1,
MultiDriver = 0x2,
/// <summary>The device is part of the desktop.</summary>
PrimaryDevice = 0x4,
/// <summary>Represents a pseudo device used to mirror application drawing for remoting or other purposes.</summary>
MirroringDriver = 0x8,
/// <summary>The device is VGA compatible.</summary>
VGACompatible = 0x10,
/// <summary>The device is removable; it cannot be the primary display.</summary>
Removable = 0x20,
/// <summary>The device has more display modes than its output devices support.</summary>
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;
}
}

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

Loading…
Cancel
Save