diff --git a/FanControl/App.config b/FanControl/App.config
index 49cc43e..4dd49e2 100644
--- a/FanControl/App.config
+++ b/FanControl/App.config
@@ -1,3 +1,15 @@
+
+
+
+
+
+
+
+
+ Default
+
+
+
\ No newline at end of file
diff --git a/FanControl/FanControl.csproj b/FanControl/FanControl.csproj
index ab2ca79..3497e99 100644
--- a/FanControl/FanControl.csproj
+++ b/FanControl/FanControl.csproj
@@ -1,4 +1,4 @@
-
+
WinExe
@@ -8,10 +8,12 @@
True
FanControl.Program
app.manifest
+ 0.1.0
+
diff --git a/FanControl/FanControlForm.Designer.cs b/FanControl/FanControlForm.Designer.cs
index 97746dc..4d606a0 100644
--- a/FanControl/FanControlForm.Designer.cs
+++ b/FanControl/FanControlForm.Designer.cs
@@ -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;
}
}
\ No newline at end of file
diff --git a/FanControl/FanControlForm.cs b/FanControl/FanControlForm.cs
index 42d565c..1fcb4a9 100644
--- a/FanControl/FanControlForm.cs
+++ b/FanControl/FanControlForm.cs
@@ -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");
+ }
}
}
diff --git a/FanControl/FromLibreHardwareMonitor/StartupManager.cs b/FanControl/FromLibreHardwareMonitor/StartupManager.cs
new file mode 100644
index 0000000..639d915
--- /dev/null
+++ b/FanControl/FromLibreHardwareMonitor/StartupManager.cs
@@ -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 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);
+ }
+ }
+}
diff --git a/FanControl/Properties/Settings.Designer.cs b/FanControl/Properties/Settings.Designer.cs
index 4bb435d..bc5d36a 100644
--- a/FanControl/Properties/Settings.Designer.cs
+++ b/FanControl/Properties/Settings.Designer.cs
@@ -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;
+ }
+ }
}
}
diff --git a/FanControl/Properties/Settings.settings b/FanControl/Properties/Settings.settings
index 049245f..fc44976 100644
--- a/FanControl/Properties/Settings.settings
+++ b/FanControl/Properties/Settings.settings
@@ -1,6 +1,9 @@
-
-
-
-
-
+
+
+
+
+ Default
+
+
+
\ No newline at end of file