/// <summary>
        /// Main method; start of the program.
        /// </summary>
        /// <param name="args">Command-line parameters</param>
        /// <returns>Status/error code</returns>
        static int Main(string[] args)
        {
            try
            {
                int   temperatureLowerThreshold = int.Parse(args[0]);
                int   temperatureUpperThreshold = int.Parse(args[1]);
                ulong rpmThreshold = ulong.Parse(args[2]);

                int sleepInterval = 1;
                if (args.Length > 3)
                {
                    sleepInterval = int.Parse(args[3]);
                }

                FixConsole();

                Console.Title           = "DellFanKeepAlive";
                Console.OutputEncoding  = Encoding.UTF8;
                Console.BackgroundColor = ConsoleColor.DarkRed;

                string titleText =
                    "DellFanKeepAlive version " + DellFanLib.Version + " • By Aaron Kelley • GPLv3 • https://github.com/AaronKelley/DellFanManagement\n" +
                    "Dell SMM I/O driver by 424778940z • https://github.com/424778940z/bzh-windrv-dell-smm-io\n" +
                    "Open Hardware Monitor version 0.9.5 • Copyright © 2009-2020 Michael Möller and contributors (MPL 2.0)\n" +
                    "Icon made from Icon Fonts (http://www.onlinewebfonts.com/icon/), licensed by CC BY 3.0\n" +
                    "\n" +
                    "Configuration: lower temperature threshold " + temperatureLowerThreshold + ", upper temperature threshold " + temperatureUpperThreshold + ", RPM threshold " + rpmThreshold + "\n" +
                    "\n";

                if (DellFanLib.Initialize())
                {
                    TemperatureReader temperatureReader = new TemperatureReader();
                    DellFanLib.EnableEcFanControl();
                    bool          ecFanControlEnabled    = true;
                    DateTime      ecFanControlChangeTime = DateTime.Now;
                    DateTime      lastUpdateTime         = DateTime.Now;
                    StringBuilder statusString           = new StringBuilder();

                    ulong rpm1;
                    ulong rpm2        = ulong.MaxValue;
                    bool  fan2Present = true;
                    bool  firstRun    = true;

                    Console.Clear();

                    while (true)
                    {
                        try
                        {
                            // Check last update time.
                            DateTime currentTime = DateTime.Now;
                            if (((DateTimeOffset)currentTime).ToUnixTimeSeconds() - ((DateTimeOffset)lastUpdateTime).ToUnixTimeSeconds() > 30)
                            {
                                lastUpdateTime = currentTime;
                                throw new Exception(string.Format("A long time passed between updates - {0} - {1}", lastUpdateTime.ToString(), currentTime.ToString()));
                            }

                            lastUpdateTime = currentTime;

                            statusString.Clear();
                            statusString.Append(titleText);
                            statusString.AppendFormat("Current time: {0,-30}\n\n", lastUpdateTime);

                            bool thresholdsMet = true;

                            IReadOnlyDictionary <string, int> temperatures = temperatureReader.GetCpuCoreTemperatures();
                            foreach (string key in temperatures.Keys)
                            {
                                int temperature = temperatures[key];

                                if (temperature > (ecFanControlEnabled ? temperatureLowerThreshold : temperatureUpperThreshold))
                                {
                                    thresholdsMet = false;
                                }
                            }

                            rpm1 = DellFanLib.GetFanRpm(FanIndex.Fan1);

                            if (fan2Present)
                            {
                                rpm2 = DellFanLib.GetFanRpm(FanIndex.Fan2);

                                if (rpm2 == uint.MaxValue && firstRun)
                                {
                                    // No fan 2.
                                    fan2Present = false;
                                }

                                firstRun = false;
                            }

                            if (rpm1 == 0 || rpm1 > rpmThreshold || (fan2Present && (rpm2 == 0 || rpm2 > rpmThreshold)))
                            {
                                thresholdsMet = false;
                            }

                            statusString.AppendFormat("Temperature and fan speed thresholds are {0,-8}\n", thresholdsMet ? "met." : "not met.");
                            statusString.AppendFormat("{0,-75}\n\n", ecFanControlEnabled ?
                                                      string.Format("The EC has had control of the system fans since {0}.", ecFanControlChangeTime.ToString()) :
                                                      string.Format("The fan speed has been locked since {0}.", ecFanControlChangeTime.ToString())
                                                      );

                            statusString.Append("System temperatures:\n");
                            foreach (string key in temperatures.Keys)
                            {
                                string temperature = temperatures[key] != 0 ? temperatures[key].ToString() : "--";
                                statusString.AppendFormat("  {0,-14}{1,3}", key, temperature);
                                CheckValues(key, temperatures[key]);
                                if (minValues.ContainsKey(key) && maxValues.ContainsKey(key))
                                {
                                    statusString.AppendFormat("  ( {0,3} - {1,3} )", minValues[key], maxValues[key]);
                                }
                                statusString.Append("\n");
                            }

                            statusString.Append("\n");
                            statusString.Append("Fan speeds:\n");
                            statusString.AppendFormat("  {0,-9}{1,5}\n", "Fan #1", rpm1);
                            if (fan2Present)
                            {
                                statusString.AppendFormat("  {0,-9}{1,5}\n", "Fan #2", rpm2);
                            }

                            if (ecFanControlEnabled && thresholdsMet)
                            {
                                DellFanLib.DisableEcFanControl();
                                ecFanControlEnabled     = false;
                                ecFanControlChangeTime  = DateTime.Now;
                                Console.BackgroundColor = ConsoleColor.DarkBlue;
                                Console.Clear();
                            }
                            else if (!ecFanControlEnabled && !thresholdsMet)
                            {
                                DellFanLib.EnableEcFanControl();
                                ecFanControlEnabled     = true;
                                ecFanControlChangeTime  = DateTime.Now;
                                Console.BackgroundColor = ConsoleColor.DarkRed;
                                Console.Clear();
                            }

                            if (errorsDetected)
                            {
                                statusString.Append("\n!! Errors detected, check error log file for details !!\n");
                            }

                            FixConsole();
                            Console.CursorLeft = 0;
                            Console.CursorTop  = 0;
                            Console.Write(statusString);
                        }
                        catch (Exception exception)
                        {
                            LogError(exception);
                        }

                        Thread.Sleep(1000 * sleepInterval);
                    }
                }
                else
                {
                    Console.Error.WriteLine("Failed to start driver.");
                    Console.Error.WriteLine();
                    Console.Error.WriteLine("Please make sure that bzh_dell_smm_io_x64.sys is present in the working directory,");
                    Console.Error.WriteLine("and that measures needed to allow the signature to be verified have been performed.");
                    Console.Error.WriteLine("Also, make sure that you are running the program \"as administrator\".");
                }
            }
            catch (DllNotFoundException)
            {
                Console.Error.WriteLine("Unable to load DellFanLib.dll");
                Console.Error.WriteLine("Make sure that the file is present.  If it is, install the required Visual C++ redistributable:");
                Console.Error.WriteLine("https://aka.ms/vs/16/release/vc_redist.x64.exe");
                return(-1);
            }
            catch (Exception exception)
            {
                Console.Error.WriteLine("Error: {0}", exception.Message);
                Console.Error.WriteLine(exception.StackTrace);
            }

            DellFanLib.Shutdown();
            return(0);
        }
Esempio n. 2
0
        /// <summary>
        /// Main method; start of the program.
        /// </summary>
        /// <param name="args">Command-line parameters</param>
        /// <returns>Status/error code</returns>
        static int Main(string[] args)
        {
            int returnCode = 0;

            try
            {
                Console.WriteLine("DellFanCmd {0}", DellFanLib.Version);
                Console.WriteLine("By Aaron Kelley");
                Console.WriteLine("Licensed under GPLv3");
                Console.WriteLine("Source code available at https://github.com/AaronKelley/DellFanManagement");
                Console.WriteLine();
                Console.WriteLine("Dell SMM I/O driver by 424778940z");
                Console.WriteLine("https://github.com/424778940z/bzh-windrv-dell-smm-io");
                Console.WriteLine();
                Console.WriteLine("Derived from \"Dell fan utility\" by 424778940z");
                Console.WriteLine("https://github.com/424778940z/dell-fan-utility");
                Console.WriteLine();

                if (args.Length != 1)
                {
                    Usage();
                }
                else
                {
                    // Behavior variables.
                    bool     disableEcFanControl = false;
                    bool     enableEcFanControl  = false;
                    bool     setFansToMax        = false;
                    bool     useAlternateCommand = false;
                    bool     setFanLevel         = false;
                    bool     getFanRpm           = false;
                    bool     runTest             = false;
                    FanIndex fanSelection        = FanIndex.Fan1;
                    FanLevel fanLevel            = FanLevel.Level0;

                    // Figure out what was requested.
                    if (args[0] == "ec-disable")
                    {
                        disableEcFanControl = true;
                        setFansToMax        = true;
                    }
                    else if (args[0] == "ec-disable-nofanchg")
                    {
                        disableEcFanControl = true;
                    }
                    else if (args[0] == "ec-enable")
                    {
                        enableEcFanControl = true;
                    }
                    else if (args[0] == "ec-disable-alt")
                    {
                        disableEcFanControl = true;
                        setFansToMax        = true;
                        useAlternateCommand = true;
                    }
                    else if (args[0] == "ec-disable-alt-nofanchg")
                    {
                        disableEcFanControl = true;
                        useAlternateCommand = true;
                    }
                    else if (args[0] == "ec-enable-alt")
                    {
                        enableEcFanControl  = true;
                        useAlternateCommand = true;
                    }
                    else if (args[0] == "fan1-level0")
                    {
                        setFanLevel  = true;
                        fanSelection = FanIndex.Fan1;
                        fanLevel     = FanLevel.Level0;
                    }
                    else if (args[0] == "fan1-level1")
                    {
                        setFanLevel  = true;
                        fanSelection = FanIndex.Fan1;
                        fanLevel     = FanLevel.Level1;
                    }
                    else if (args[0] == "fan1-level2")
                    {
                        setFanLevel  = true;
                        fanSelection = FanIndex.Fan1;
                        fanLevel     = FanLevel.Level2;
                    }
                    else if (args[0] == "fan2-level0")
                    {
                        setFanLevel  = true;
                        fanSelection = FanIndex.Fan2;
                        fanLevel     = FanLevel.Level0;
                    }
                    else if (args[0] == "fan2-level1")
                    {
                        setFanLevel  = true;
                        fanSelection = FanIndex.Fan2;
                        fanLevel     = FanLevel.Level1;
                    }
                    else if (args[0] == "fan2-level2")
                    {
                        setFanLevel  = true;
                        fanSelection = FanIndex.Fan2;
                        fanLevel     = FanLevel.Level2;
                    }
                    else if (args[0] == "rpm-fan1")
                    {
                        getFanRpm    = true;
                        fanSelection = FanIndex.Fan1;
                    }
                    else if (args[0] == "rpm-fan2")
                    {
                        getFanRpm    = true;
                        fanSelection = FanIndex.Fan2;
                    }
                    else if (args[0] == "test")
                    {
                        runTest = true;
                    }
                    else if (args[0] == "test-alt")
                    {
                        runTest             = true;
                        useAlternateCommand = true;
                    }
                    else
                    {
                        Usage();
                        return(-3);
                    }

                    // Execute request.

                    // Load driver first.
                    if (LoadDriver())
                    {
                        if (disableEcFanControl)
                        {
                            // Disable EC fan control.
                            Console.WriteLine("Attempting to disable EC control of the fan...");

                            ulong result = DellFanLib.DisableEcFanControl(useAlternateCommand);

                            if (result == ulong.MaxValue)
                            {
                                Console.Error.WriteLine("Failed.");
                                UnloadDriver();
                                return(-1);
                            }

                            Console.WriteLine(" ...Success.");

                            if (setFansToMax)
                            {
                                // Crank the fans up, for safety.
                                Console.WriteLine("Setting fan 1 speed to maximum...");
                                result = DellFanLib.SetFanLevel(FanIndex.Fan1, FanLevel.Level2);
                                if (result == ulong.MaxValue)
                                {
                                    Console.Error.WriteLine("Failed.");
                                }

                                Console.WriteLine("Setting fan 2 speed to maximum...");
                                result = DellFanLib.SetFanLevel(FanIndex.Fan2, FanLevel.Level2);
                                if (result == ulong.MaxValue)
                                {
                                    Console.Error.WriteLine("Failed.  (Maybe your system just has one fan?)");
                                }
                            }
                            else
                            {
                                Console.WriteLine("WARNING: CPU and GPU are not designed to run under load without active cooling.");
                                Console.WriteLine("Make sure that you have alternate fan speed control measures in place.");
                            }
                        }
                        else if (enableEcFanControl)
                        {
                            // Enable EC fan control.
                            Console.WriteLine("Attempting to enable EC control of the fan...");

                            ulong result = DellFanLib.EnableEcFanControl(useAlternateCommand);

                            if (result == ulong.MaxValue)
                            {
                                Console.Error.WriteLine("Failed.");
                                UnloadDriver();
                                return(-1);
                            }

                            Console.WriteLine(" ...Success.");
                        }
                        else if (setFanLevel)
                        {
                            // Set the fan to a specific level.
                            Console.WriteLine("Attempting to set the fan level...");
                            ulong result = DellFanLib.SetFanLevel(fanSelection, fanLevel);

                            if (result == ulong.MaxValue)
                            {
                                Console.Error.WriteLine("Failed.");
                                UnloadDriver();
                                return(-1);
                            }

                            Console.WriteLine(" ...Success.");
                        }
                        else if (getFanRpm)
                        {
                            // Query the fan RPM.
                            Console.WriteLine("Attempting to query the fan RPM...");
                            ulong result = DellFanLib.GetFanRpm(fanSelection);

                            if (result == ulong.MaxValue)
                            {
                                Console.Error.WriteLine("Failed.");
                                UnloadDriver();
                                return(-1);
                            }

                            Console.WriteLine(" Result: {0}", result);
                            returnCode = int.Parse(result.ToString());
                        }
                        else if (runTest)
                        {
                            // Test all of the fan levels and report RPMs.

                            ulong rpmIdleFan1;
                            ulong rpmLevel0Fan1;
                            ulong rpmLevel1Fan1;
                            ulong rpmLevel2Fan1;

                            ulong?rpmIdleFan2   = null;
                            ulong?rpmLevel0Fan2 = null;
                            ulong?rpmLevel1Fan2 = null;
                            ulong?rpmLevel2Fan2 = null;

                            int  sleepInterval = 7500;
                            bool fan2Present   = true;

                            // Disable EC fan control.
                            Console.WriteLine("Disabling EC fan control...");
                            DellFanLib.DisableEcFanControl(useAlternateCommand);

                            // Query current idle fan levels.
                            rpmIdleFan1 = DellFanLib.GetFanRpm(FanIndex.Fan1);
                            DellFanLib.SetFanLevel(FanIndex.Fan1, FanLevel.Level0);

                            rpmIdleFan2 = DellFanLib.GetFanRpm(FanIndex.Fan2);
                            ulong result = DellFanLib.SetFanLevel(FanIndex.Fan2, FanLevel.Level0);

                            if (result == uint.MaxValue)
                            {
                                // No fan 2?
                                fan2Present = false;
                                Console.WriteLine("Looks like fan 2 is not present, system only has one fan?");
                            }

                            // Measure fan 1.
                            Console.WriteLine("Measuring: Fan 1, level 0...");
                            Thread.Sleep(sleepInterval);
                            rpmLevel0Fan1 = DellFanLib.GetFanRpm(FanIndex.Fan1);

                            Console.WriteLine("Measuring: Fan 1, level 1...");
                            DellFanLib.SetFanLevel(FanIndex.Fan1, FanLevel.Level1);
                            Thread.Sleep(sleepInterval);
                            rpmLevel1Fan1 = DellFanLib.GetFanRpm(FanIndex.Fan1);

                            Console.WriteLine("Measuring: Fan 1, level 2...");
                            DellFanLib.SetFanLevel(FanIndex.Fan1, FanLevel.Level2);
                            Thread.Sleep(sleepInterval);
                            rpmLevel2Fan1 = DellFanLib.GetFanRpm(FanIndex.Fan1);

                            DellFanLib.SetFanLevel(FanIndex.Fan1, FanLevel.Level0);

                            if (fan2Present)
                            {
                                // Measure fan 2.
                                Console.WriteLine("Measuring: Fan 2, level 0...");
                                rpmLevel0Fan2 = DellFanLib.GetFanRpm(FanIndex.Fan2);

                                Console.WriteLine("Measuring: Fan 2, level 1...");
                                DellFanLib.SetFanLevel(FanIndex.Fan2, FanLevel.Level1);
                                Thread.Sleep(sleepInterval);
                                rpmLevel1Fan2 = DellFanLib.GetFanRpm(FanIndex.Fan2);

                                Console.WriteLine("Measuring: Fan 2, level 2...");
                                DellFanLib.SetFanLevel(FanIndex.Fan2, FanLevel.Level2);
                                Thread.Sleep(sleepInterval);
                                rpmLevel2Fan2 = DellFanLib.GetFanRpm(FanIndex.Fan2);
                            }

                            // Enable EC fan control.
                            Console.WriteLine("Enabling EC fan control...");
                            DellFanLib.EnableEcFanControl(useAlternateCommand);

                            Console.WriteLine("Test procedure is finished.");
                            Console.WriteLine();
                            Console.WriteLine();

                            // Output results.
                            Console.WriteLine("Fan 1 initial speed: {0}", rpmIdleFan1);
                            if (fan2Present)
                            {
                                Console.WriteLine("Fan 2 initial speed: {0}", rpmIdleFan2);
                            }
                            Console.WriteLine();

                            Console.WriteLine("Fan 1 level 0 speed: {0}", rpmLevel0Fan1);
                            Console.WriteLine("Fan 1 level 1 speed: {0}", rpmLevel1Fan1);
                            Console.WriteLine("Fan 1 level 2 speed: {0}", rpmLevel2Fan1);
                            Console.WriteLine();

                            if (fan2Present)
                            {
                                Console.WriteLine("Fan 2 level 0 speed: {0}", rpmLevel0Fan2);
                                Console.WriteLine("Fan 2 level 1 speed: {0}", rpmLevel1Fan2);
                                Console.WriteLine("Fan 2 level 2 speed: {0}", rpmLevel2Fan2);
                                Console.WriteLine();
                            }
                        }

                        // Unload driver.
                        UnloadDriver();
                    }
                }
            }
            catch (DllNotFoundException)
            {
                Console.Error.WriteLine("Unable to load DellFanLib.dll");
                Console.Error.WriteLine("Make sure that the file is present.  If it is, install the required Visual C++ redistributable:");
                Console.Error.WriteLine("https://aka.ms/vs/16/release/vc_redist.x64.exe");
                returnCode = -1;
            }
            catch (Exception exception)
            {
                Console.Error.WriteLine("Error: {0}", exception.Message);
                Console.Error.WriteLine(exception.StackTrace);
                returnCode = -1;
                UnloadDriver();
            }

            return(returnCode);
        }