diff --git a/app/ASUSWmi.cs b/app/ASUSWmi.cs index 8f7815113..58c7a25ce 100644 --- a/app/ASUSWmi.cs +++ b/app/ASUSWmi.cs @@ -316,4 +316,5 @@ public void SubscribeToEvents(Action EventHandler } } + } diff --git a/app/Fans.Designer.cs b/app/Fans.Designer.cs index 3fec40897..bd093cbd9 100644 --- a/app/Fans.Designer.cs +++ b/app/Fans.Designer.cs @@ -38,6 +38,7 @@ private void InitializeComponent() ChartArea chartArea3 = new ChartArea(); Title title3 = new Title(); panelFans = new Panel(); + labelFansResult = new Label(); labelTip = new Label(); labelBoost = new Label(); comboBoost = new RComboBox(); @@ -63,7 +64,16 @@ private void InitializeComponent() trackTotal = new TrackBar(); pictureFine = new PictureBox(); labelInfo = new Label(); - labelFansResult = new Label(); + panelGPU = new Panel(); + buttonResetGPU = new RButton(); + labelGPUMemory = new Label(); + trackGPUMemory = new TrackBar(); + labelGPUMemoryTitle = new Label(); + pictureBox2 = new PictureBox(); + labelGPUCore = new Label(); + labelGPU = new Label(); + trackGPUCore = new TrackBar(); + labelGPUCoreTitle = new Label(); panelFans.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)picturePerf).BeginInit(); tableFanCharts.SuspendLayout(); @@ -77,6 +87,10 @@ private void InitializeComponent() panelTotal.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)trackTotal).BeginInit(); ((System.ComponentModel.ISupportInitialize)pictureFine).BeginInit(); + panelGPU.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)trackGPUMemory).BeginInit(); + ((System.ComponentModel.ISupportInitialize)pictureBox2).BeginInit(); + ((System.ComponentModel.ISupportInitialize)trackGPUCore).BeginInit(); SuspendLayout(); // // panelFans @@ -91,13 +105,24 @@ private void InitializeComponent() panelFans.Controls.Add(checkApplyFans); panelFans.Controls.Add(buttonReset); panelFans.Dock = DockStyle.Left; - panelFans.Location = new Point(364, 0); + panelFans.Location = new Point(711, 0); panelFans.Margin = new Padding(0); panelFans.Name = "panelFans"; panelFans.Padding = new Padding(10); - panelFans.Size = new Size(824, 1159); + panelFans.Size = new Size(824, 1189); panelFans.TabIndex = 12; // + // labelFansResult + // + labelFansResult.Anchor = AnchorStyles.Top | AnchorStyles.Right; + labelFansResult.ForeColor = Color.Red; + labelFansResult.Location = new Point(30, 1073); + labelFansResult.Name = "labelFansResult"; + labelFansResult.Size = new Size(760, 32); + labelFansResult.TabIndex = 41; + labelFansResult.TextAlign = ContentAlignment.TopRight; + labelFansResult.Visible = false; + // // labelTip // labelTip.AutoSize = true; @@ -160,7 +185,7 @@ private void InitializeComponent() tableFanCharts.RowStyles.Add(new RowStyle(SizeType.Percent, 33F)); tableFanCharts.RowStyles.Add(new RowStyle(SizeType.Percent, 33F)); tableFanCharts.RowStyles.Add(new RowStyle(SizeType.Percent, 33F)); - tableFanCharts.Size = new Size(764, 992); + tableFanCharts.Size = new Size(764, 1022); tableFanCharts.TabIndex = 36; // // chartGPU @@ -168,10 +193,10 @@ private void InitializeComponent() chartArea1.Name = "ChartArea1"; chartGPU.ChartAreas.Add(chartArea1); chartGPU.Dock = DockStyle.Fill; - chartGPU.Location = new Point(2, 340); + chartGPU.Location = new Point(2, 350); chartGPU.Margin = new Padding(2, 10, 2, 10); chartGPU.Name = "chartGPU"; - chartGPU.Size = new Size(760, 310); + chartGPU.Size = new Size(760, 320); chartGPU.TabIndex = 17; chartGPU.Text = "chartGPU"; title1.Name = "Title1"; @@ -185,7 +210,7 @@ private void InitializeComponent() chartCPU.Location = new Point(2, 10); chartCPU.Margin = new Padding(2, 10, 2, 10); chartCPU.Name = "chartCPU"; - chartCPU.Size = new Size(760, 310); + chartCPU.Size = new Size(760, 320); chartCPU.TabIndex = 14; chartCPU.Text = "chartCPU"; title2.Name = "Title1"; @@ -196,10 +221,10 @@ private void InitializeComponent() chartArea3.Name = "ChartArea3"; chartMid.ChartAreas.Add(chartArea3); chartMid.Dock = DockStyle.Fill; - chartMid.Location = new Point(2, 670); + chartMid.Location = new Point(2, 690); chartMid.Margin = new Padding(2, 10, 2, 10); chartMid.Name = "chartMid"; - chartMid.Size = new Size(760, 312); + chartMid.Size = new Size(760, 322); chartMid.TabIndex = 14; chartMid.Text = "chartMid"; title3.Name = "Title3"; @@ -222,7 +247,7 @@ private void InitializeComponent() checkApplyFans.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; checkApplyFans.AutoSize = true; checkApplyFans.BackColor = SystemColors.ControlLight; - checkApplyFans.Location = new Point(449, 1088); + checkApplyFans.Location = new Point(449, 1118); checkApplyFans.Margin = new Padding(4, 2, 4, 2); checkApplyFans.Name = "checkApplyFans"; checkApplyFans.Padding = new Padding(15, 5, 15, 5); @@ -239,7 +264,7 @@ private void InitializeComponent() buttonReset.BorderColor = Color.Transparent; buttonReset.BorderRadius = 2; buttonReset.FlatStyle = FlatStyle.Flat; - buttonReset.Location = new Point(30, 1082); + buttonReset.Location = new Point(30, 1112); buttonReset.Margin = new Padding(4, 2, 4, 2); buttonReset.Name = "buttonReset"; buttonReset.Secondary = true; @@ -258,11 +283,11 @@ private void InitializeComponent() panelPower.Controls.Add(pictureFine); panelPower.Controls.Add(labelInfo); panelPower.Dock = DockStyle.Left; - panelPower.Location = new Point(0, 0); + panelPower.Location = new Point(347, 0); panelPower.Margin = new Padding(10); panelPower.Name = "panelPower"; panelPower.Padding = new Padding(10); - panelPower.Size = new Size(364, 1159); + panelPower.Size = new Size(364, 1189); panelPower.TabIndex = 13; // // pictureBox1 @@ -293,7 +318,7 @@ private void InitializeComponent() checkApplyPower.Anchor = AnchorStyles.Bottom | AnchorStyles.Left; checkApplyPower.AutoSize = true; checkApplyPower.BackColor = SystemColors.ControlLight; - checkApplyPower.Location = new Point(20, 1088); + checkApplyPower.Location = new Point(20, 1118); checkApplyPower.Margin = new Padding(4, 2, 4, 2); checkApplyPower.Name = "checkApplyPower"; checkApplyPower.Padding = new Padding(15, 5, 15, 5); @@ -418,24 +443,147 @@ private void InitializeComponent() labelInfo.TabIndex = 19; labelInfo.Text = "label"; // - // labelFansResult - // - labelFansResult.Anchor = AnchorStyles.Top | AnchorStyles.Right; - labelFansResult.ForeColor = Color.Red; - labelFansResult.Location = new Point(30, 1073); - labelFansResult.Name = "labelFansResult"; - labelFansResult.Size = new Size(760, 32); - labelFansResult.TabIndex = 41; - labelFansResult.TextAlign = ContentAlignment.TopRight; + // panelGPU + // + panelGPU.Controls.Add(buttonResetGPU); + panelGPU.Controls.Add(labelGPUMemory); + panelGPU.Controls.Add(trackGPUMemory); + panelGPU.Controls.Add(labelGPUMemoryTitle); + panelGPU.Controls.Add(pictureBox2); + panelGPU.Controls.Add(labelGPUCore); + panelGPU.Controls.Add(labelGPU); + panelGPU.Controls.Add(trackGPUCore); + panelGPU.Controls.Add(labelGPUCoreTitle); + panelGPU.Dock = DockStyle.Left; + panelGPU.Location = new Point(0, 0); + panelGPU.Name = "panelGPU"; + panelGPU.Size = new Size(347, 1189); + panelGPU.TabIndex = 14; + // + // buttonResetGPU + // + buttonResetGPU.Activated = false; + buttonResetGPU.Anchor = AnchorStyles.Bottom | AnchorStyles.Left; + buttonResetGPU.BackColor = SystemColors.ControlLight; + buttonResetGPU.BorderColor = Color.Transparent; + buttonResetGPU.BorderRadius = 2; + buttonResetGPU.FlatStyle = FlatStyle.Flat; + buttonResetGPU.Location = new Point(48, 1110); + buttonResetGPU.Margin = new Padding(4, 2, 4, 2); + buttonResetGPU.Name = "buttonResetGPU"; + buttonResetGPU.Secondary = true; + buttonResetGPU.Size = new Size(232, 54); + buttonResetGPU.TabIndex = 43; + buttonResetGPU.Text = "Reset Clocks"; + buttonResetGPU.UseVisualStyleBackColor = false; + // + // labelGPUMemory + // + labelGPUMemory.AutoSize = true; + labelGPUMemory.Font = new Font("Segoe UI", 9F, FontStyle.Bold, GraphicsUnit.Point); + labelGPUMemory.Location = new Point(184, 112); + labelGPUMemory.Name = "labelGPUMemory"; + labelGPUMemory.Size = new Size(130, 32); + labelGPUMemory.TabIndex = 42; + labelGPUMemory.Text = "2000 MHz"; + labelGPUMemory.TextAlign = ContentAlignment.MiddleCenter; + // + // trackGPUMemory + // + trackGPUMemory.LargeChange = 100; + trackGPUMemory.Location = new Point(216, 160); + trackGPUMemory.Margin = new Padding(4, 2, 4, 2); + trackGPUMemory.Maximum = 300; + trackGPUMemory.Minimum = 0; + trackGPUMemory.Name = "trackGPUMemory"; + trackGPUMemory.Orientation = Orientation.Vertical; + trackGPUMemory.Size = new Size(90, 454); + trackGPUMemory.SmallChange = 10; + trackGPUMemory.TabIndex = 41; + trackGPUMemory.TickFrequency = 50; + trackGPUMemory.Value = 0; + // + // labelGPUMemoryTitle + // + labelGPUMemoryTitle.AutoSize = true; + labelGPUMemoryTitle.Location = new Point(167, 72); + labelGPUMemoryTitle.Name = "labelGPUMemoryTitle"; + labelGPUMemoryTitle.Size = new Size(169, 32); + labelGPUMemoryTitle.TabIndex = 40; + labelGPUMemoryTitle.Text = "Memory Clock"; + labelGPUMemoryTitle.TextAlign = ContentAlignment.MiddleCenter; + // + // pictureBox2 + // + pictureBox2.BackgroundImage = Properties.Resources.icons8_video_card_48; + pictureBox2.BackgroundImageLayout = ImageLayout.Zoom; + pictureBox2.ErrorImage = null; + pictureBox2.InitialImage = null; + pictureBox2.Location = new Point(25, 17); + pictureBox2.Margin = new Padding(4, 2, 4, 2); + pictureBox2.Name = "pictureBox2"; + pictureBox2.Size = new Size(36, 38); + pictureBox2.TabIndex = 39; + pictureBox2.TabStop = false; + // + // labelGPUCore + // + labelGPUCore.AutoSize = true; + labelGPUCore.Font = new Font("Segoe UI", 9F, FontStyle.Bold, GraphicsUnit.Point); + labelGPUCore.Location = new Point(20, 112); + labelGPUCore.Name = "labelGPUCore"; + labelGPUCore.Size = new Size(130, 32); + labelGPUCore.TabIndex = 28; + labelGPUCore.Text = "1500 MHz"; + labelGPUCore.TextAlign = ContentAlignment.MiddleCenter; + // + // labelGPU + // + labelGPU.AutoSize = true; + labelGPU.Font = new Font("Segoe UI", 9F, FontStyle.Bold, GraphicsUnit.Point); + labelGPU.Location = new Point(60, 19); + labelGPU.Margin = new Padding(4, 0, 4, 0); + labelGPU.Name = "labelGPU"; + labelGPU.Size = new Size(162, 32); + labelGPU.TabIndex = 27; + labelGPU.Text = "GPU Settings"; + // + // trackGPUCore + // + trackGPUCore.LargeChange = 100; + trackGPUCore.Location = new Point(48, 160); + trackGPUCore.Margin = new Padding(4, 2, 4, 2); + trackGPUCore.Maximum = 300; + trackGPUCore.Minimum = 0; + trackGPUCore.Name = "trackGPUCore"; + trackGPUCore.Orientation = Orientation.Vertical; + trackGPUCore.RightToLeft = RightToLeft.No; + trackGPUCore.Size = new Size(90, 454); + trackGPUCore.SmallChange = 10; + trackGPUCore.TabIndex = 17; + trackGPUCore.TickFrequency = 50; + trackGPUCore.TickStyle = TickStyle.TopLeft; + trackGPUCore.Value = 0; + // + // labelGPUCoreTitle + // + labelGPUCoreTitle.AutoSize = true; + labelGPUCoreTitle.Location = new Point(22, 72); + labelGPUCoreTitle.Name = "labelGPUCoreTitle"; + labelGPUCoreTitle.Size = new Size(129, 32); + labelGPUCoreTitle.TabIndex = 16; labelFansResult.Visible = false; - // - // Fans - // - AutoScaleDimensions = new SizeF(192F, 192F); + labelGPUCoreTitle.TextAlign = ContentAlignment.MiddleCenter; + labelGPUCoreTitle.Text = "Core Clock"; + // + // Fans + // + AutoScaleDimensions = new SizeF(192F, 192F); AutoScaleMode = AutoScaleMode.Dpi; AutoSize = true; AutoSizeMode = AutoSizeMode.GrowAndShrink; - ClientSize = new Size(1178, 1159); + ClientSize = new Size(1542, 1189); + Controls.Add(panelGPU); Controls.Add(panelFans); Controls.Add(panelPower); Margin = new Padding(4, 2, 4, 2); @@ -465,6 +613,11 @@ private void InitializeComponent() panelTotal.PerformLayout(); ((System.ComponentModel.ISupportInitialize)trackTotal).EndInit(); ((System.ComponentModel.ISupportInitialize)pictureFine).EndInit(); + panelGPU.ResumeLayout(false); + panelGPU.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)trackGPUMemory).EndInit(); + ((System.ComponentModel.ISupportInitialize)pictureBox2).EndInit(); + ((System.ComponentModel.ISupportInitialize)trackGPUCore).EndInit(); ResumeLayout(false); } @@ -496,5 +649,15 @@ private void InitializeComponent() private Label labelBoost; private Label labelTip; private Label labelFansResult; + private Panel panelGPU; + private Label labelGPUCore; + private Label labelGPU; + private TrackBar trackGPUCore; + private Label labelGPUCoreTitle; + private PictureBox pictureBox2; + private Label labelGPUMemory; + private TrackBar trackGPUMemory; + private Label labelGPUMemoryTitle; + private RButton buttonResetGPU; } } \ No newline at end of file diff --git a/app/Fans.cs b/app/Fans.cs index 22673f819..4b50649e3 100644 --- a/app/Fans.cs +++ b/app/Fans.cs @@ -1,6 +1,7 @@ using System.Diagnostics; using System.Windows.Forms.DataVisualization.Charting; using CustomControls; +using GHelper.Gpu; namespace GHelper { @@ -63,6 +64,11 @@ public Fans() checkApplyFans.Click += CheckApplyFans_Click; checkApplyPower.Click += CheckApplyPower_Click; + trackGPUCore.Scroll += trackGPU_Scroll; + trackGPUMemory.Scroll += trackGPU_Scroll; + + buttonResetGPU.Click += ButtonResetGPU_Click; + //labelInfo.MaximumSize = new Size(280, 0); labelInfo.Text = Properties.Strings.PPTExperimental; @@ -74,6 +80,57 @@ public Fans() Shown += Fans_Shown; + InitGPUClocks(); + + } + + private void InitGPUClocks() + { + + panelGPU.Visible = HardwareMonitor.GpuControl.IsNvidia; + + trackGPUCore.Value = Math.Min(Program.config.getConfig("GPUCore"), 300); + trackGPUMemory.Value = Math.Min(Program.config.getConfig("GPUMemory"), 300); + + VisualiseGPUClocks(); + } + + private void ButtonResetGPU_Click(object? sender, EventArgs e) + { + + Program.RunAsAdmin(); + + try + { + trackGPUCore.Value = 0; + trackGPUMemory.Value = 0; + VisualiseGPUClocks(); + } + catch (Exception ex) + { + Logger.WriteLine(ex.ToString()); + } + } + + private void VisualiseGPUClocks() + { + labelGPUCore.Text = $"+{trackGPUCore.Value} MHz"; + labelGPUMemory.Text = $"+{trackGPUMemory.Value} MHz"; + } + + private void trackGPU_Scroll(object? sender, EventArgs e) + { + VisualiseGPUClocks(); + + try + { + Program.config.setConfig("GPUCore", trackGPUCore.Value); + Program.config.setConfig("GPUMemory", trackGPUMemory.Value); + } + catch (Exception ex) + { + Logger.WriteLine(ex.ToString()); + } } static string ChartPercToRPM(int percentage, string unit = "") @@ -532,6 +589,7 @@ private void AdjustAllLevels(int index, double curXVal, double curYVal, Series s } } } + } } diff --git a/app/GHelper.csproj b/app/GHelper.csproj index 8b488d8e4..01a004d01 100644 --- a/app/GHelper.csproj +++ b/app/GHelper.csproj @@ -13,26 +13,26 @@ AnyCPU;x64 8.0 GHelper - x64 + AnyCPU False True 0.56 - none + embedded - none + embedded - none + embedded - none + embedded diff --git a/app/Gpu/AmdGpuTemperatureProvider.cs b/app/Gpu/AmdGpuControl.cs similarity index 96% rename from app/Gpu/AmdGpuTemperatureProvider.cs rename to app/Gpu/AmdGpuControl.cs index 35d79bb3d..6352b3d45 100644 --- a/app/Gpu/AmdGpuTemperatureProvider.cs +++ b/app/Gpu/AmdGpuControl.cs @@ -4,12 +4,15 @@ namespace GHelper.Gpu; // Reference: https://github.com/GPUOpen-LibrariesAndSDKs/display-library/blob/master/Sample-Managed/Program.cs -public class AmdGpuTemperatureProvider : IGpuTemperatureProvider { +public class AmdGpuControl : IGpuControl { private bool _isReady; private IntPtr _adlContextHandle; private readonly ADLAdapterInfo _internalDiscreteAdapter; - public AmdGpuTemperatureProvider() { + public bool IsNvidia => false; + + + public AmdGpuControl() { if (!Adl2.Load()) return; @@ -104,7 +107,7 @@ public void Dispose() { GC.SuppressFinalize(this); } - ~AmdGpuTemperatureProvider() { + ~AmdGpuControl() { ReleaseUnmanagedResources(); } } diff --git a/app/Gpu/IGpuTemperatureProvider.cs b/app/Gpu/IGpuControl.cs similarity index 60% rename from app/Gpu/IGpuTemperatureProvider.cs rename to app/Gpu/IGpuControl.cs index f126d1539..f54a77254 100644 --- a/app/Gpu/IGpuTemperatureProvider.cs +++ b/app/Gpu/IGpuControl.cs @@ -1,6 +1,7 @@ namespace GHelper.Gpu; -public interface IGpuTemperatureProvider : IDisposable { +public interface IGpuControl : IDisposable { + bool IsNvidia { get; } bool IsValid { get; } int? GetCurrentTemperature(); int? GetGpuUse(); diff --git a/app/Gpu/NvidiaGpuTemperatureProvider.cs b/app/Gpu/NvidiaGpuControl.cs similarity index 92% rename from app/Gpu/NvidiaGpuTemperatureProvider.cs rename to app/Gpu/NvidiaGpuControl.cs index 03261e427..0360591d2 100644 --- a/app/Gpu/NvidiaGpuTemperatureProvider.cs +++ b/app/Gpu/NvidiaGpuControl.cs @@ -5,17 +5,19 @@ namespace GHelper.Gpu; -public class NvidiaGpuTemperatureProvider : IGpuTemperatureProvider +public class NvidiaGpuControl : IGpuControl { private readonly PhysicalGPU? _internalGpu; - public NvidiaGpuTemperatureProvider() + public NvidiaGpuControl() { _internalGpu = GetInternalDiscreteGpu(); } public bool IsValid => _internalGpu != null; + public bool IsNvidia => IsValid; + public int? GetCurrentTemperature() { if (!IsValid) diff --git a/app/HardwareMonitor.cs b/app/HardwareMonitor.cs index e213a1bca..f5a5bf53c 100644 --- a/app/HardwareMonitor.cs +++ b/app/HardwareMonitor.cs @@ -1,11 +1,10 @@ using GHelper; using GHelper.Gpu; using System.Diagnostics; -using System.Management; public static class HardwareMonitor { - private static IGpuTemperatureProvider? GpuTemperatureProvider; + public static IGpuControl? GpuControl; public static float? cpuTemp = -1; public static float? batteryDischarge = -1; @@ -51,7 +50,7 @@ private static int GetGpuUse() { try { - int? gpuUse = GpuTemperatureProvider?.GetGpuUse(); + int? gpuUse = GpuControl?.GetGpuUse(); if (gpuUse is not null) return (int)gpuUse; } catch (Exception ex) @@ -76,20 +75,20 @@ public static void ReadSensors() cpuTemp = Program.wmi.DeviceGet(ASUSWmi.Temp_CPU); if (cpuTemp < 0) try - { - using (var ct = new PerformanceCounter("Thermal Zone Information", "Temperature", @"\_TZ.THRM", true)) { - cpuTemp = ct.NextValue() - 273; + using (var ct = new PerformanceCounter("Thermal Zone Information", "Temperature", @"\_TZ.THRM", true)) + { + cpuTemp = ct.NextValue() - 273; + } + } + catch + { + Debug.WriteLine("Failed reading CPU temp"); } - } - catch - { - Debug.WriteLine("Failed reading CPU temp"); - } try { - gpuTemp = GpuTemperatureProvider?.GetCurrentTemperature(); + gpuTemp = GpuControl?.GetCurrentTemperature(); } catch (Exception ex) @@ -121,7 +120,7 @@ public static bool IsUsedGPU(int threshold = 20) { Thread.Sleep(1000); return (GetGpuUse() > threshold); - } + } return false; } @@ -144,28 +143,28 @@ public static void RecreateGpuTemperatureProvider() { try { - GpuTemperatureProvider?.Dispose(); + GpuControl?.Dispose(); // Detect valid GPU temperature provider. // We start with NVIDIA because there's always at least an integrated AMD GPU - IGpuTemperatureProvider gpuTemperatureProvider = new NvidiaGpuTemperatureProvider(); - if (gpuTemperatureProvider.IsValid) + IGpuControl _gpuControl = new NvidiaGpuControl(); + if (_gpuControl.IsValid) { - GpuTemperatureProvider = gpuTemperatureProvider; + GpuControl = _gpuControl; return; } - gpuTemperatureProvider.Dispose(); - gpuTemperatureProvider = new AmdGpuTemperatureProvider(); - if (gpuTemperatureProvider.IsValid) + _gpuControl.Dispose(); + _gpuControl = new AmdGpuControl(); + if (_gpuControl.IsValid) { - GpuTemperatureProvider = gpuTemperatureProvider; + GpuControl = _gpuControl; return; } - gpuTemperatureProvider.Dispose(); + _gpuControl.Dispose(); - GpuTemperatureProvider = null; + GpuControl = null; } catch (Exception ex) { diff --git a/app/Keyboard.cs b/app/Keyboard.cs index c9261caa1..8c3735771 100644 --- a/app/Keyboard.cs +++ b/app/Keyboard.cs @@ -14,6 +14,7 @@ public partial class Keyboard : RForm {"play", Properties.Strings.PlayPause}, {"aura", Properties.Strings.ToggleAura}, {"ghelper", Properties.Strings.OpenGHelper}, + {"screen", Properties.Strings.ToggleScreen}, {"custom", Properties.Strings.Custom} }; diff --git a/app/NativeMethods.cs b/app/NativeMethods.cs index 7f23031d8..8296b9f4d 100644 --- a/app/NativeMethods.cs +++ b/app/NativeMethods.cs @@ -351,6 +351,33 @@ public static IEnumerable GetAllDevices() public class NativeMethods { + private const int WM_SYSCOMMAND = 0x0112; + private const int SC_MONITORPOWER = 0xF170; + private const int MONITOR_OFF = 2; + + [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] + private static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam); + + [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] + private static extern uint FormatMessage(uint dwFlags, IntPtr lpSource, uint dwMessageId, uint dwLanguageId, out string lpBuffer, uint nSize, IntPtr Arguments); + + public static void TurnOffScreen(IntPtr handle) + { + IntPtr result = SendMessage(handle, WM_SYSCOMMAND, (IntPtr)SC_MONITORPOWER, (IntPtr)MONITOR_OFF); + if (result == IntPtr.Zero) + { + int error = Marshal.GetLastWin32Error(); + string message = ""; + uint formatFlags = 0x00001000 | 0x00000200 | 0x00000100 | 0x00000080; + uint formatResult = FormatMessage(formatFlags, IntPtr.Zero, (uint)error, 0, out message, 0, IntPtr.Zero); + if (formatResult == 0) + { + message = "Unknown error."; + } + Logger.WriteLine($"Failed to turn off screen. Error code: {error}. {message}"); + } + } + // Monitor Power detection internal const uint DEVICE_NOTIFY_WINDOW_HANDLE = 0x0; diff --git a/app/Program.cs b/app/Program.cs index d172097c0..e867d14ff 100644 --- a/app/Program.cs +++ b/app/Program.cs @@ -2,6 +2,7 @@ using System.Diagnostics; using System.Globalization; using System.Management; +using System.Security.Principal; using Tools; namespace GHelper @@ -27,23 +28,62 @@ static class Program private static long lastTheme; private static PowerLineStatus isPlugged = PowerLineStatus.Unknown; + + static void CheckProcesses() + { + Process currentProcess = Process.GetCurrentProcess(); + Process[] processes = Process.GetProcessesByName(currentProcess.ProcessName); + + if (processes.Length > 1) + { + foreach (Process process in processes) + if (process.Id != currentProcess.Id) + try + { + process.Kill(); + } + catch (Exception ex) + { + Logger.WriteLine(ex.ToString()); + MessageBox.Show(Properties.Strings.AppAlreadyRunningText, Properties.Strings.AppAlreadyRunning, MessageBoxButtons.OK); + Application.Exit(); + return; + } + } + } + + static bool IsUserAdministrator() + { + WindowsIdentity identity = WindowsIdentity.GetCurrent(); + WindowsPrincipal principal = new WindowsPrincipal(identity); + return principal.IsInRole(WindowsBuiltInRole.Administrator); + } + + public static void RunAsAdmin() + { + // Check if the current user is an administrator + if (!IsUserAdministrator()) + { + ProcessStartInfo startInfo = new ProcessStartInfo(); + startInfo.UseShellExecute = true; + startInfo.WorkingDirectory = Environment.CurrentDirectory; + startInfo.FileName = Application.ExecutablePath; + startInfo.Verb = "runas"; + Process.Start(startInfo); + //Application.Exit(); + } + } + // The main entry point for the application public static void Main() { Thread.CurrentThread.CurrentUICulture = CultureInfo.CurrentUICulture; - Debug.WriteLine(CultureInfo.CurrentUICulture); //Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture("es"); - if (Process.GetProcesses().Count(p => p.ProcessName == "GHelper") > 1) - { - MessageBox.Show(Properties.Strings.AppAlreadyRunningText, Properties.Strings.AppAlreadyRunning, MessageBoxButtons.OK); - Application.Exit(); - return; - } - + CheckProcesses(); try { @@ -99,8 +139,6 @@ public static void Main() SettingsToggle(); } - - Application.Run(); @@ -167,19 +205,18 @@ private static void SystemEvents_PowerModeChanged(object sender, PowerModeChange } - static void LaunchProcess(string fileName = "") + static void LaunchProcess(string command = "") { - ProcessStartInfo start = new ProcessStartInfo(); - start.FileName = fileName; - start.WindowStyle = ProcessWindowStyle.Hidden; - start.CreateNoWindow = true; + string executable = command.Split(' ')[0]; + string arguments = command.Substring(executable.Length).Trim(); + try { - Process proc = Process.Start(start); + Process proc = Process.Start(executable, arguments); } catch { - Logger.WriteLine("Failed to run " + fileName); + Logger.WriteLine("Failed to run " + command); } @@ -230,6 +267,9 @@ static void KeyProcess(string name = "m3") case "screenshot": NativeMethods.KeyPress(NativeMethods.VK_SNAPSHOT); break; + case "screen": + NativeMethods.TurnOffScreen(Program.settingsForm.Handle); + break; case "aura": settingsForm.BeginInvoke(settingsForm.CycleAuraMode); break; diff --git a/app/Properties/Strings.Designer.cs b/app/Properties/Strings.Designer.cs index 47e6a2b3a..7fbf076d0 100644 --- a/app/Properties/Strings.Designer.cs +++ b/app/Properties/Strings.Designer.cs @@ -861,6 +861,15 @@ internal static string ToggleAura { } } + /// + /// Looks up a localized string similar to Toggle Screen. + /// + internal static string ToggleScreen { + get { + return ResourceManager.GetString("ToggleScreen", resourceCulture); + } + } + /// /// Looks up a localized string similar to Turbo. /// diff --git a/app/Properties/Strings.resx b/app/Properties/Strings.resx index 20186d998..e5913e811 100644 --- a/app/Properties/Strings.resx +++ b/app/Properties/Strings.resx @@ -384,6 +384,9 @@ Toggle Aura + + Toggle Screen + Turbo diff --git a/app/Properties/Strings.zh-CN.resx b/app/Properties/Strings.zh-CN.resx index d4f0c229a..9fff9f03b 100644 --- a/app/Properties/Strings.zh-CN.resx +++ b/app/Properties/Strings.zh-CN.resx @@ -328,7 +328,7 @@ 自动切换 - 使用电池时关闭独显(集显模式),并在插上电源后重新启用独显(混合输出) + 使用电池时切换到集显模式,并在插上电源后重新启用标准模式 其他 diff --git a/app/app.manifest b/app/app.manifest index e16db2fed..296860c62 100644 --- a/app/app.manifest +++ b/app/app.manifest @@ -4,7 +4,9 @@ -