Store Fan mode in settings and add startup on boot

This commit is contained in:
Kamil Trzciński 2022-11-12 12:22:19 +01:00
parent 29903834a6
commit d56d123e61
7 changed files with 307 additions and 19 deletions

View file

@ -1,3 +1,15 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<section name="FanControl.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
</sectionGroup>
</configSections>
<userSettings>
<FanControl.Properties.Settings>
<setting name="FanMode" serializeAs="String">
<value>Default</value>
</setting>
</FanControl.Properties.Settings>
</userSettings>
</configuration>

View file

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
@ -8,10 +8,12 @@
<UseWindowsForms>True</UseWindowsForms>
<StartupObject>FanControl.Program</StartupObject>
<ApplicationManifest>app.manifest</ApplicationManifest>
<AssemblyVersion>0.1.0</AssemblyVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="LibreHardwareMonitorLib" Version="0.9.1" />
<PackageReference Include="TaskScheduler" Version="2.10.1" />
</ItemGroup>
<ItemGroup>

View file

@ -39,11 +39,14 @@
this.menuStrip1 = new System.Windows.Forms.MenuStrip();
this.fanModeSelectMenu = new System.Windows.Forms.ToolStripComboBox();
this.controlToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItemStartupOnBoot = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator();
this.exitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.propertyGridUpdateTimer = new System.Windows.Forms.Timer(this.components);
this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
this.sensorWarningLabel = new System.Windows.Forms.Label();
this.propertyGrid1 = new System.Windows.Forms.PropertyGrid();
this.label1 = new System.Windows.Forms.Label();
this.contextMenu.SuspendLayout();
this.menuStrip1.SuspendLayout();
this.tableLayoutPanel1.SuspendLayout();
@ -119,15 +122,29 @@
// controlToolStripMenuItem
//
this.controlToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.toolStripMenuItemStartupOnBoot,
this.toolStripSeparator2,
this.exitToolStripMenuItem});
this.controlToolStripMenuItem.Name = "controlToolStripMenuItem";
this.controlToolStripMenuItem.Size = new System.Drawing.Size(113, 40);
this.controlToolStripMenuItem.Text = "&Control";
//
// toolStripMenuItemStartupOnBoot
//
this.toolStripMenuItemStartupOnBoot.Name = "toolStripMenuItemStartupOnBoot";
this.toolStripMenuItemStartupOnBoot.Size = new System.Drawing.Size(315, 44);
this.toolStripMenuItemStartupOnBoot.Text = "&Startup on Boot";
this.toolStripMenuItemStartupOnBoot.Click += new System.EventHandler(this.toolStripMenuItemStartupOnBoot_Click);
//
// toolStripSeparator2
//
this.toolStripSeparator2.Name = "toolStripSeparator2";
this.toolStripSeparator2.Size = new System.Drawing.Size(312, 6);
//
// exitToolStripMenuItem
//
this.exitToolStripMenuItem.Name = "exitToolStripMenuItem";
this.exitToolStripMenuItem.Size = new System.Drawing.Size(184, 44);
this.exitToolStripMenuItem.Size = new System.Drawing.Size(315, 44);
this.exitToolStripMenuItem.Text = "&Exit";
this.exitToolStripMenuItem.Click += new System.EventHandler(this.formClose_Event);
//
@ -143,12 +160,14 @@
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel1.Controls.Add(this.sensorWarningLabel, 0, 1);
this.tableLayoutPanel1.Controls.Add(this.propertyGrid1, 0, 0);
this.tableLayoutPanel1.Controls.Add(this.label1, 0, 2);
this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 44);
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
this.tableLayoutPanel1.RowCount = 2;
this.tableLayoutPanel1.RowCount = 3;
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel1.Size = new System.Drawing.Size(712, 885);
this.tableLayoutPanel1.TabIndex = 5;
//
@ -159,7 +178,7 @@
this.sensorWarningLabel.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.sensorWarningLabel.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point);
this.sensorWarningLabel.ForeColor = System.Drawing.Color.Red;
this.sensorWarningLabel.Location = new System.Drawing.Point(3, 757);
this.sensorWarningLabel.Location = new System.Drawing.Point(3, 725);
this.sensorWarningLabel.Name = "sensorWarningLabel";
this.sensorWarningLabel.Size = new System.Drawing.Size(706, 128);
this.sensorWarningLabel.TabIndex = 6;
@ -175,10 +194,25 @@
this.propertyGrid1.HelpVisible = false;
this.propertyGrid1.Location = new System.Drawing.Point(3, 3);
this.propertyGrid1.Name = "propertyGrid1";
this.propertyGrid1.Size = new System.Drawing.Size(706, 751);
this.propertyGrid1.Size = new System.Drawing.Size(706, 719);
this.propertyGrid1.TabIndex = 1;
this.propertyGrid1.ToolbarVisible = false;
//
// label1
//
this.label1.AutoSize = true;
this.label1.Dock = System.Windows.Forms.DockStyle.Fill;
this.label1.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.label1.Font = new System.Drawing.Font("Segoe UI", 9F, ((System.Drawing.FontStyle)((System.Drawing.FontStyle.Bold | System.Drawing.FontStyle.Underline))), System.Drawing.GraphicsUnit.Point);
this.label1.ForeColor = System.Drawing.SystemColors.HotTrack;
this.label1.Location = new System.Drawing.Point(3, 853);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(706, 32);
this.label1.TabIndex = 7;
this.label1.Text = "https://github.com/ayufan-research/SteamDeckTools";
this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
this.label1.DoubleClick += new System.EventHandler(this.label1_DoubleClick);
//
// FanControlForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(13F, 32F);
@ -188,9 +222,12 @@
this.Controls.Add(this.menuStrip1);
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.MainMenuStrip = this.menuStrip1;
this.MaximizeBox = false;
this.Name = "FanControlForm";
this.ShowInTaskbar = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Steam Deck Fan Control";
this.WindowState = System.Windows.Forms.FormWindowState.Minimized;
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.FanControlForm_FormClosing);
this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.FanControlForm_FormClosed);
this.contextMenu.ResumeLayout(false);
@ -219,5 +256,8 @@
private TableLayoutPanel tableLayoutPanel1;
private Label sensorWarningLabel;
private PropertyGrid propertyGrid1;
private ToolStripMenuItem toolStripMenuItemStartupOnBoot;
private ToolStripSeparator toolStripSeparator2;
private Label label1;
}
}

View file

@ -1,8 +1,10 @@
using System;
using FanControl.FromLibreHardwareMonitor;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.Common;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Net.Sockets;
@ -15,11 +17,18 @@ namespace FanControl
public partial class FanControlForm : Form
{
private FanController fanControl = new FanController();
private StartupManager startupManager = new StartupManager();
public FanControlForm()
{
InitializeComponent();
Text += " v" + Application.ProductVersion.ToString();
notifyIcon.Text = Text;
toolStripMenuItemStartupOnBoot.Visible = startupManager.IsAvailable;
toolStripMenuItemStartupOnBoot.Checked = startupManager.Startup;
propertyGrid1.SelectedObject = fanControl;
propertyGrid1.ExpandAllGridItems();
@ -29,19 +38,33 @@ namespace FanControl
fanModeSelectNotifyMenu.Items.Add(item);
}
fanModeSelectMenu.SelectedIndex = 0;
fanModeSelectNotifyMenu.SelectedIndex = 0;
try
{
var fanMode = Enum.Parse(typeof(FanController.FanMode), Properties.Settings.Default.FanMode);
setFanMode((FanController.FanMode)fanMode);
}
catch(System.ArgumentException)
{
setFanMode(FanController.FanMode.Default);
}
notifyIcon.ShowBalloonTip(3000, "Steam Deck Fan Control", "Fan Control Started", ToolTipIcon.Info);
notifyIcon.ShowBalloonTip(3000, Text, "Fan Control Started", ToolTipIcon.Info);
}
private void setFanMode(FanController.FanMode mode)
{
fanControl.SetMode(mode);
fanModeSelectMenu.SelectedItem = mode;
fanModeSelectNotifyMenu.SelectedItem = mode;
Properties.Settings.Default["FanMode"] = mode.ToString();
Properties.Settings.Default.Save();
}
private void fanModeSelect_SelectedValueChanged(object sender, EventArgs e)
{
var comboBox = (ToolStripComboBox)sender;
var selectedMode = (FanController.FanMode)comboBox.SelectedItem;
fanControl.SetMode(selectedMode);
fanModeSelectMenu.SelectedItem = selectedMode;
fanModeSelectNotifyMenu.SelectedItem = selectedMode;
setFanMode(selectedMode);
}
private void FanControlForm_FormClosing(object sender, FormClosingEventArgs e)
@ -49,13 +72,13 @@ namespace FanControl
if (e.CloseReason == CloseReason.UserClosing && Visible)
{
e.Cancel = true;
Hide();
WindowState = FormWindowState.Minimized;
}
}
private void formShow_Event(object sender, EventArgs e)
{
Show();
WindowState = FormWindowState.Normal;
propertyGrid1.Refresh();
}
@ -87,5 +110,16 @@ namespace FanControl
sensorWarningLabel.Visible = fanControl.IsAnyInvalid();
notifyIcon.Text = String.Format("Fan: {0} RPM Mode: {1}", fanControl.CurrentRPM, fanControl.Mode);
}
private void toolStripMenuItemStartupOnBoot_Click(object sender, EventArgs e)
{
startupManager.Startup = !startupManager.Startup;
toolStripMenuItemStartupOnBoot.Checked = startupManager.Startup;
}
private void label1_DoubleClick(object sender, EventArgs e)
{
System.Diagnostics.Process.Start("http://github.com/ayufan-research/SteamDeckTools");
}
}
}

View file

@ -0,0 +1,185 @@
// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
// If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
// Copyright (C) LibreHardwareMonitor and Contributors.
// Partial Copyright (C) Michael Möller <mmoeller@openhardwaremonitor.org> and Contributors.
// All Rights Reserved.
using System;
using System.IO;
using System.Linq;
using System.Security;
using System.Security.Principal;
using System.Windows.Forms;
using Microsoft.Win32;
using Microsoft.Win32.TaskScheduler;
using Action = Microsoft.Win32.TaskScheduler.Action;
using Task = Microsoft.Win32.TaskScheduler.Task;
namespace FanControl.FromLibreHardwareMonitor
{
public class StartupManager
{
private const string RegistryPath = @"Software\Microsoft\Windows\CurrentVersion\Run";
private bool _startup;
public const string Description = "Starts Steam Deck Fan Control on Windows startup.";
public const string NameOf = "Steam Deck Fan Control";
public StartupManager()
{
if (Environment.OSVersion.Platform >= PlatformID.Unix)
{
IsAvailable = false;
return;
}
if (IsAdministrator() && TaskService.Instance.Connected)
{
IsAvailable = true;
Task task = GetTask();
if (task != null)
{
foreach (Action action in task.Definition.Actions)
{
if (action.ActionType == TaskActionType.Execute && action is ExecAction execAction)
{
if (execAction.Path.Equals(Application.ExecutablePath, StringComparison.OrdinalIgnoreCase))
_startup = true;
}
}
}
}
else
{
try
{
using (RegistryKey registryKey = Registry.CurrentUser.OpenSubKey(RegistryPath))
{
string value = (string)registryKey?.GetValue(NameOf);
if (value != null)
_startup = value == Application.ExecutablePath;
}
IsAvailable = true;
}
catch (SecurityException)
{
IsAvailable = false;
}
}
}
public bool IsAvailable { get; }
public bool Startup
{
get { return _startup; }
set
{
if (_startup != value)
{
if (IsAvailable)
{
if (TaskService.Instance.Connected)
{
if (value)
CreateTask();
else
DeleteTask();
_startup = value;
}
else
{
try
{
if (value)
CreateRegistryKey();
else
DeleteRegistryKey();
_startup = value;
}
catch (UnauthorizedAccessException)
{
throw new InvalidOperationException();
}
}
}
else
{
throw new InvalidOperationException();
}
}
}
}
private static bool IsAdministrator()
{
try
{
WindowsIdentity identity = WindowsIdentity.GetCurrent();
WindowsPrincipal principal = new WindowsPrincipal(identity);
return principal.IsInRole(WindowsBuiltInRole.Administrator);
}
catch
{
return false;
}
}
private static Task GetTask()
{
try
{
return TaskService.Instance.AllTasks.FirstOrDefault(x => x.Name.Equals(NameOf, StringComparison.OrdinalIgnoreCase));
}
catch
{
return null;
}
}
private void CreateTask()
{
TaskDefinition taskDefinition = TaskService.Instance.NewTask();
taskDefinition.RegistrationInfo.Description = Description;
taskDefinition.Triggers.Add(new LogonTrigger());
taskDefinition.Settings.StartWhenAvailable = true;
taskDefinition.Settings.DisallowStartIfOnBatteries = false;
taskDefinition.Settings.StopIfGoingOnBatteries = false;
taskDefinition.Settings.ExecutionTimeLimit = TimeSpan.Zero;
taskDefinition.Settings.AllowHardTerminate = false;
taskDefinition.Principal.RunLevel = TaskRunLevel.Highest;
taskDefinition.Principal.LogonType = TaskLogonType.InteractiveToken;
taskDefinition.Actions.Add(new ExecAction(Application.ExecutablePath, "", Path.GetDirectoryName(Application.ExecutablePath)));
TaskService.Instance.RootFolder.RegisterTaskDefinition(NameOf, taskDefinition);
}
private static void DeleteTask()
{
Task task = GetTask();
task?.Folder.DeleteTask(task.Name, false);
}
private static void CreateRegistryKey()
{
RegistryKey registryKey = Registry.CurrentUser.CreateSubKey(RegistryPath);
registryKey?.SetValue(NameOf, Application.ExecutablePath);
}
private static void DeleteRegistryKey()
{
RegistryKey registryKey = Registry.CurrentUser.CreateSubKey(RegistryPath);
registryKey?.DeleteValue(NameOf);
}
}
}

View file

@ -22,5 +22,17 @@ namespace FanControl.Properties {
return defaultInstance;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("Default")]
public string FanMode {
get {
return ((string)(this["FanMode"]));
}
set {
this["FanMode"] = value;
}
}
}
}

View file

@ -1,6 +1,9 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
<Profiles>
<Profile Name="(Default)" />
</Profiles>
</SettingsFile>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="FanControl.Properties" GeneratedClassName="Settings">
<Profiles />
<Settings>
<Setting Name="FanMode" Type="System.String" Scope="User">
<Value Profile="(Default)">Default</Value>
</Setting>
</Settings>
</SettingsFile>