Skip to content

Add Windows startup and draggable fan curve control#77

Closed
ciresnave wants to merge 1 commit into
Karmel0x:masterfrom
ciresnave:master
Closed

Add Windows startup and draggable fan curve control#77
ciresnave wants to merge 1 commit into
Karmel0x:masterfrom
ciresnave:master

Conversation

@ciresnave

Copy link
Copy Markdown

Summary

This PR adds two user-facing improvements to Asus Fan Control:

  • automatic launch at Windows sign-in
  • a draggable 5-point temperature-to-fan-speed curve editor in the GUI

It also fixes a curve persistence issue where saved curve values could be overwritten during startup before the saved settings were fully restored.

What Changed

  • added Windows sign-in startup registration from the GUI
  • changed startup registration to use a scheduled task that launches run.bat
  • added minimized startup support for sign-in launch
  • bundled run.bat with the GUI build output
  • added warnings when the app is started without the launcher context required on some ASUS systems
  • added persistent fan-control mode and curve settings
  • replaced the curve point editor with a draggable line graph
  • updated curve interpolation so the applied fan speed matches the displayed graph behavior
  • bumped version to 1.2.0
  • updated README.md and added CHANGELOG.md

Why

Some ASUS laptops only expose working fan control when the app is launched through the existing elevated run.bat / PsExec flow. A plain Run-key startup was not sufficient on the affected machine, so startup registration now preserves that working launch path.

The new graph editor also makes the temperature curve much easier to use, and the startup fix ensures saved curve settings are preserved correctly across restarts.

Validation

  • built successfully with:

    msbuild AsusFanControl.sln /t:Build /p:Configuration=Release

  • manually verified:

    • launch at Windows sign-in
    • minimized startup to tray
    • restored access to the window from the tray
    • saved curve persistence across restart
    • draggable graph editing behavior
    • curve-based fan control on the target ASUS system

Notes

On systems that require the original launcher flow, the app still needs to be started through run.bat, which elevates and launches the GUI in the context required for hardware access.

Copilot AI review requested due to automatic review settings April 13, 2026 02:54

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds Windows sign-in startup registration (via a scheduled task that runs run.bat) and replaces the temperature-to-fan-speed curve editor with a draggable 5-point graph, while also persisting/restoring fan control state and curve settings more reliably during startup.

Changes:

  • Added startup registration support (scheduled task + minimized-to-tray launch) and bundled run.bat into GUI output.
  • Added a draggable temperature curve graph editor and updated interpolation/application logic to match the graph.
  • Persisted fan-control enablement + curve enablement/values and bumped versioning/docs (README + CHANGELOG).

Reviewed changes

Copilot reviewed 15 out of 16 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
run.bat Adds an elevation + PsExec launcher flow used by sign-in startup and systems requiring SYSTEM context.
README.md Documents new startup registration option and curve editor behavior/requirements.
CHANGELOG.md Adds release notes for 1.1.0/1.2.0 changes.
AsusFanControlGUI/StartupRegistration.cs Implements scheduled-task based sign-in startup registration and legacy Run-key cleanup.
AsusFanControlGUI/Properties/Settings.settings Adds persisted settings for control enablement and temperature curve.
AsusFanControlGUI/Properties/Settings.Designer.cs Adds strongly-typed accessors for new persisted settings.
AsusFanControlGUI/Properties/AssemblyInfo.cs Bumps GUI assembly version to 1.2.0.0.
AsusFanControlGUI/Program.cs Adds --minimized argument parsing and passes it into the main form.
AsusFanControlGUI/Form1.cs Integrates startup registration UI, tray/minimized startup, curve enablement, and curve-based control loop.
AsusFanControlGUI/FanCurveGraphControl.cs Adds draggable line-graph control for editing the 5-point curve.
AsusFanControlGUI/FanCurve.cs Adds fan-curve model, serialization, parsing, and interpolation helpers.
AsusFanControlGUI/AsusFanControlGUI.csproj Includes new curve/startup sources, copies run.bat to output, adds net472 reference assemblies package.
AsusFanControlGUI/App.config Adds default values for the new persisted user settings.
AsusFanControl/Properties/AssemblyInfo.cs Bumps core library assembly version to 1.2.0.0.
AsusFanControl/AsusFanControl.csproj Adds net472 reference assemblies package.
AsusFanControl/AsusControl.cs Changes fan multi-set pacing to synchronous Thread.Sleep between fan updates.
Files not reviewed (1)
  • AsusFanControlGUI/Properties/Settings.Designer.cs: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +143 to +151
try
{
fanCurve = new FanCurve(points);
return true;
}
catch (ArgumentException)
{
return false;
}
Comment on lines +33 to 42
public void SetFanSpeeds(byte value)
{
var fanCount = AsusWinIO64.HealthyTable_FanCounts();
for(byte fanIndex = 0; fanIndex < fanCount; fanIndex++)
for (byte fanIndex = 0; fanIndex < fanCount; fanIndex++)
{
SetFanSpeed(value, fanIndex);
await Task.Delay(20);

if (fanIndex + 1 < fanCount)
Thread.Sleep(20);
}
Comment on lines +90 to +96
return string.Format("\"{0}\" {1}", launcherPath, StartMinimizedArgument);
}

private static string BuildCreateScheduledTaskScript()
{
var targetUserName = EscapeForPowerShellSingleQuotedLiteral(GetTargetUserName());
var actionArguments = EscapeForPowerShellSingleQuotedLiteral(string.Format("/c \"\"{0}\"\" {1}", GetLauncherPath(), StartMinimizedArgument));
Comment on lines +208 to +214
return output.IndexOf("cannot find", StringComparison.OrdinalIgnoreCase) >= 0 ||
output.IndexOf("cannot find the file specified", StringComparison.OrdinalIgnoreCase) >= 0 ||
output.IndexOf("does not exist", StringComparison.OrdinalIgnoreCase) >= 0;
}

private static SchtasksResult RunSchtasks(string arguments)
{
Comment on lines +208 to +214
private void SyncStartupRegistrationState()
{
try
{
var isEnabled = StartupRegistration.IsEnabled();
if (isEnabled)
StartupRegistration.RefreshCurrentExecutablePath();
@ciresnave

Copy link
Copy Markdown
Author

Pull request #75 has most of what I added. Probably consider merging that one instead of this. Sorry for the duplicate work.

@ciresnave ciresnave closed this Apr 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants