Example #1
0
        /// <summary>
        /// checks if any theme needs an update because the runtimeconfig differs from the actual configured state
        /// </summary>
        /// <param name="config">AutoDarkModeConfig instance</param>
        /// <param name="newTheme">new theme that is requested</param>
        /// <returns></returns>
        private static bool ThemeOptionsNeedUpdate(AdmConfig config, Theme newTheme)
        {
            RuntimeConfig rtc = RuntimeConfig.Instance();

            if (config.Wallpaper.Enabled)
            {
                if (rtc.CurrentWallpaperTheme == Theme.Undefined || rtc.CurrentWallpaperTheme != newTheme)
                {
                    return(true);
                }
            }

            if (config.SystemTheme != Mode.LightOnly)
            {
                // if accent color is enabled in config, accent color is enabled in windows
                // and the target theme is light we need to update
                if (config.AccentColorTaskbarEnabled && rtc.CurrentColorPrevalence && newTheme == Theme.Light)
                {
                    return(true);
                }
                // if accent color is enabled in config, but it's not currently active, update
                else if (config.AccentColorTaskbarEnabled && !rtc.CurrentColorPrevalence)
                {
                    return(true);
                }
                // if accent color is disabled in config but still active, we need to disable it
                else if (!config.AccentColorTaskbarEnabled && rtc.CurrentColorPrevalence)
                {
                    return(true);
                }
            }

            if (ComponentNeedsUpdate(config.SystemTheme, rtc.CurrentSystemTheme, newTheme))
            {
                return(true);
            }

            if (ComponentNeedsUpdate(config.AppsTheme, rtc.CurrentAppsTheme, newTheme))
            {
                return(true);
            }

            if (ComponentNeedsUpdate(config.EdgeTheme, rtc.CurrentEdgeTheme, newTheme))
            {
                return(true);
            }

            if (WallpaperNeedsUpdate(config.Wallpaper.Enabled, rtc.CurrentWallpaperPath, config.Wallpaper.LightThemeWallpapers,
                                     config.Wallpaper.DarkThemeWallpapers, rtc.CurrentWallpaperTheme, newTheme))
            {
                return(true);
            }

            if (config.Office.Enabled && ComponentNeedsUpdate(config.Office.Mode, rtc.CurrentOfficeTheme, newTheme))
            {
                return(true);
            }

            if (config.ColorFilterEnabled && ColorFilterNeedsUpdate(config.ColorFilterEnabled, rtc.ColorFilterEnabled, newTheme))
            {
                return(true);
            }

            return(false);
        }
Example #2
0
        /// <summary>
        /// Parses a command message and invokes a callback function delegate for status reporting
        /// </summary>
        /// <param name="msg">list of messages to parse</param>
        /// <param name="SendResponse">Callback taking a string as parameter to report return values back to sender</param>
        /// <param name="service">Service class for invoking application exit</param>
        public static void Parse(List <string> msg, Action <string> SendResponse, Service service)
        {
            AdmConfigBuilder builder = AdmConfigBuilder.Instance();
            RuntimeConfig    rtc     = RuntimeConfig.Instance();

            msg.ForEach(message =>
            {
                switch (message)
                {
                case Command.Switch:
                    Logger.Info("signal received: time based theme switch");
                    ThemeManager.TimedSwitch(builder);
                    SendResponse(Response.Ok);
                    break;

                case Command.Swap:
                    Logger.Info("signal received: swap themes");
                    if (RegistryHandler.AppsUseLightTheme())
                    {
                        ThemeManager.SwitchTheme(builder.Config, Theme.Dark);
                    }
                    else
                    {
                        ThemeManager.SwitchTheme(builder.Config, Theme.Light);
                    }
                    SendResponse(Response.Ok);
                    break;

                case Command.AddAutostart:
                    Logger.Info("signal received: adding service to autostart");
                    bool regOk;
                    bool taskOk;
                    if (builder.Config.Tunable.UseLogonTask)
                    {
                        regOk  = RegistryHandler.RemoveAutoStart();
                        taskOk = TaskSchdHandler.CreateLogonTask();
                    }
                    else
                    {
                        taskOk = TaskSchdHandler.RemoveLogonTask();
                        regOk  = RegistryHandler.AddAutoStart();
                    }
                    if (regOk && taskOk)
                    {
                        SendResponse(Response.Ok);
                    }
                    else
                    {
                        SendResponse(Response.Err);
                    }
                    break;

                case Command.RemoveAutostart:
                    Logger.Info("signal received: removing service from autostart");
                    bool ok;
                    if (builder.Config.Tunable.UseLogonTask)
                    {
                        ok = TaskSchdHandler.RemoveLogonTask();
                    }
                    else
                    {
                        ok = RegistryHandler.RemoveAutoStart();
                    }
                    if (ok)
                    {
                        SendResponse(Response.Ok);
                    }
                    else
                    {
                        SendResponse(Response.Err);
                    }
                    break;

                case Command.Location:
                    Logger.Info("signal received: request location update");
                    Task <bool> geoTask = Task.Run(() => LocationHandler.UpdateGeoposition(AdmConfigBuilder.Instance()));
                    geoTask.Wait();
                    var result = geoTask.Result;
                    if (result)
                    {
                        SendResponse(Response.Ok);
                    }
                    else
                    {
                        SendResponse(Response.NoLocAccess);
                    }
                    break;

                case Command.UpdateConfig:
                    Logger.Info("signal received: updating configuration files");
                    try
                    {
                        AdmConfigBuilder.Instance().Load();
                        AdmConfigBuilder.Instance().LoadLocationData();
                        SendResponse(Response.Ok);
                    }
                    catch (Exception e)
                    {
                        Logger.Error(e, "could not read config file");
                        SendResponse(Response.Err);
                    }
                    break;

                case Command.Update:
                    Logger.Info("signal received: checking for update");
                    SendResponse(UpdateHandler.CheckNewVersion());
                    break;

                case Command.Shutdown:
                    Logger.Info("signal received, exiting");
                    SendResponse(Response.Ok);
                    service.Exit(null, null);
                    break;

                case Command.TestError:
                    Logger.Info("signal received: test error");
                    SendResponse(Response.Err);
                    break;

                case Command.Alive:
                    Logger.Info("signal received: request for running status");
                    SendResponse(Response.Ok);
                    break;

                case Command.Light:
                    Logger.Info("signal received: force light theme");
                    rtc.ForcedTheme = Theme.Light;
                    ThemeManager.SwitchTheme(builder.Config, Theme.Light);
                    SendResponse(Response.Ok);
                    break;

                case Command.Dark:
                    Logger.Info("signal received: force dark theme");
                    rtc.ForcedTheme = Theme.Dark;
                    ThemeManager.SwitchTheme(builder.Config, Theme.Dark);
                    SendResponse(Response.Ok);
                    break;

                case Command.NoForce:
                    Logger.Info("signal received: resetting forced modes");
                    rtc.ForcedTheme = Theme.Undefined;
                    ThemeManager.TimedSwitch(builder);
                    SendResponse(Response.Ok);
                    break;

                default:
                    Logger.Debug("unknown message received");
                    SendResponse(Response.Err);
                    break;
                }
            });
        }
        /// <summary>
        /// Parses a command message and invokes a callback function delegate for status reporting
        /// </summary>
        /// <param name="msg">list of messages to parse</param>
        /// <param name="SendResponse">Callback taking a string as parameter to report return values back to sender</param>
        /// <param name="service">Service class for invoking application exit</param>
        public static void Parse(List <string> msg, Action <string> SendResponse, Service service)
        {
            AdmConfigBuilder Properties = AdmConfigBuilder.Instance();
            RuntimeConfig    rtc        = RuntimeConfig.Instance();

            msg.ForEach(message =>
            {
                switch (message)
                {
                case Command.Switch:
                    Logger.Info("signal received: time based theme switch");
                    ThemeManager.TimedSwitch(Properties);
                    SendResponse(Command.Ok);
                    break;

                case Command.Swap:
                    Logger.Info("signal received: swap themes");
                    if (RegistryHandler.AppsUseLightTheme())
                    {
                        ThemeManager.SwitchTheme(Properties.Config, Theme.Dark);
                    }
                    else
                    {
                        ThemeManager.SwitchTheme(Properties.Config, Theme.Light);
                    }
                    SendResponse(Command.Ok);
                    break;

                case Command.AddAutostart:
                    Logger.Info("signal received: adding service to autostart");
                    RegistryHandler.AddAutoStart();
                    SendResponse(Command.Ok);
                    break;

                case Command.RemoveAutostart:
                    Logger.Info("signal received: removing service from autostart");
                    RegistryHandler.RemoveAutoStart();
                    SendResponse(Command.Ok);
                    break;

                case Command.CreateTask:
                    Logger.Info("signal received: creating win scheduler based time switch task");
                    try
                    {
                        DateTime sunrise = Convert.ToDateTime(Properties.Config.Sunrise);
                        DateTime sunset  = Convert.ToDateTime(Properties.Config.Sunset);
                        if (Properties.Config.Location.Enabled)
                        {
                            LocationHandler.GetSunTimesWithOffset(Properties, out sunrise, out sunset);
                        }
                        TaskSchdHandler.CreateSwitchTask(sunrise.Hour, sunrise.Minute, sunset.Hour, sunset.Minute);
                        SendResponse(Command.Ok);
                    }
                    catch (FormatException e)
                    {
                        Logger.Error(e, "could not create win scheduler tasks");
                        SendResponse(Command.Err);
                        Console.WriteLine(e);
                    }
                    break;

                case Command.RemoveTask:

                    Logger.Info("signal received: removing win tasks");
                    TaskSchdHandler.RemoveTasks();
                    SendResponse(Command.Ok);
                    break;

                case Command.Location:
                    Logger.Info("signal received: request location update");
                    Task <bool> geoTask = Task.Run(() => LocationHandler.UpdateGeoposition(AdmConfigBuilder.Instance()));
                    geoTask.Wait();
                    var result = geoTask.Result;
                    if (result)
                    {
                        SendResponse(Command.Ok);
                    }
                    else
                    {
                        SendResponse(Command.NoLocAccess);
                    }
                    break;

                case Command.UpdateConfig:
                    Logger.Info("signal received: updating configuration files");
                    try
                    {
                        AdmConfigBuilder.Instance().Load();
                        AdmConfigBuilder.Instance().LoadLocationData();
                        SendResponse(Command.Ok);
                    }
                    catch (Exception e)
                    {
                        Logger.Error(e, "could not read config file");
                        SendResponse(Command.Err);
                    }
                    break;

                case Command.Update:
                    Logger.Info("signal received: checking for update");
                    SendResponse(UpdateHandler.CheckNewVersion());
                    break;

                case Command.Shutdown:
                    Logger.Info("signal received, exiting");
                    SendResponse(Command.Ok);
                    service.Exit(null, null);
                    break;

                case Command.TestError:
                    Logger.Info("signal received: test error");
                    SendResponse(Command.Err);
                    break;

                case Command.Alive:
                    Logger.Info("signal received: request for running status");
                    SendResponse(Command.Ok);
                    break;

                case Command.Light:
                    Logger.Info("signal received: force light theme");
                    rtc.ForcedTheme = Theme.Light;
                    ThemeManager.SwitchTheme(Properties.Config, Theme.Light);
                    SendResponse(Command.Ok);
                    break;

                case Command.Dark:
                    Logger.Info("signal received: force dark theme");
                    rtc.ForcedTheme = Theme.Dark;
                    ThemeManager.SwitchTheme(Properties.Config, Theme.Dark);
                    SendResponse(Command.Ok);
                    break;

                case Command.NoForce:
                    Logger.Info("signal received: resetting forced modes");
                    rtc.ForcedTheme = Theme.Undefined;
                    ThemeManager.TimedSwitch(Properties);
                    SendResponse(Command.Ok);
                    break;

                default:
                    Logger.Debug("unknown message received");
                    SendResponse(Command.Err);
                    break;
                }
            });
        }
 /// <summary>
 /// Instantiates a new TimeSwitchModule.
 /// This module switches themes based on system time and sunrise/sunset
 /// </summary>
 /// <param name="name">unique name of the module</param>
 public ThemeUpdateModule(string name, bool fireOnRegistration) : base(name, fireOnRegistration)
 {
     RuntimeConfigInstance = RuntimeConfig.Instance();
 }
Example #5
0
        static void Main(string[] args)
        {
            try
            {
                //Set up Logger
                var config    = new NLog.Config.LoggingConfiguration();
                var configDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "AutoDarkMode");
                try
                {
                    Directory.CreateDirectory(configDir);
                }
                catch (Exception e)
                {
                    Logger.Debug(e, "could not create config directory");
                }

                // Targets where to log to: File and Console
                var logfile = new NLog.Targets.FileTarget("logfile")
                {
                    FileName = Path.Combine(configDir, "service.log"),
                    Layout   = @"${date:format=yyyy-MM-dd HH\:mm\:ss} | ${level} | " +
                               "${callsite:includeNamespace=False:" +
                               "cleanNamesOfAnonymousDelegates=true:" +
                               "cleanNamesOfAsyncContinuations=true}: ${message} ${exception:separator=|}"
                };
                var logconsole = new NLog.Targets.ColoredConsoleTarget("logconsole")
                {
                    Layout = @"${date:format=yyyy-MM-dd HH\:mm\:ss} | ${level} | " +
                             "${callsite:includeNamespace=False:" +
                             "cleanNamesOfAnonymousDelegates=true:" +
                             "cleanNamesOfAsyncContinuations=true}: ${message} ${exception:separator=|}"
                };

                List <string> argsList;
                if (args.Length > 0)
                {
                    argsList = new List <string>(args);
                }
                else
                {
                    argsList = new List <string>();
                }

                // Rules for mapping loggers to targets
                config.AddRule(LogLevel.Debug, LogLevel.Fatal, logconsole);
                if (argsList.Contains("/debug"))
                {
                    config.AddRule(LogLevel.Debug, LogLevel.Fatal, logfile);
                }
                else
                {
                    config.AddRule(LogLevel.Info, LogLevel.Fatal, logfile);
                }

                // Apply config
                LogManager.Configuration = config;


                if (!mutex.WaitOne(TimeSpan.FromSeconds(2), false))
                {
                    Logger.Debug("app instance already open");
                    return;
                }

                //Instantiate Runtime config
                RuntimeConfig.Instance();

                //Populate configuration
                AdmConfigBuilder Builder = AdmConfigBuilder.Instance();
                try
                {
                    Builder.Load();
                    Builder.LoadLocationData();
                    Logger.Debug("config builder instantiated and configuration loaded");
                }
                catch (Exception e)
                {
                    Logger.Fatal(e, "could not read config file. shutting down application!");
                    NLog.LogManager.Shutdown();
                    System.Environment.Exit(-1);
                }
                //if a path is set to null, set it to the currently actvie theme for convenience reasons
                bool configUpdateNeeded = false;
                if (!File.Exists(Builder.Config.DarkThemePath) || Builder.Config.DarkThemePath == null)
                {
                    Builder.Config.DarkThemePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)
                                                                + @"\Microsoft\Windows\Themes", ThemeHandler.GetCurrentThemeName() + ".theme");
                    configUpdateNeeded = true;
                }
                if (!File.Exists(Builder.Config.DarkThemePath) || Builder.Config.LightThemePath == null)
                {
                    Builder.Config.LightThemePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)
                                                                 + @"\Microsoft\Windows\Themes", ThemeHandler.GetCurrentThemeName() + ".theme");
                    configUpdateNeeded = true;
                }
                if (configUpdateNeeded)
                {
                    Logger.Warn("one or more theme paths not set at program start, reinstantiation needed");
                    try
                    {
                        Builder.Save();
                    }
                    catch (Exception ex)
                    {
                        Logger.Error(ex, "couldn't save configuration file");
                    }
                }

                int timerMillis = 0;
                if (args.Length != 0)
                {
                    Int32.TryParse(args[0], out timerMillis);
                }
                timerMillis = (timerMillis == 0) ? TimerFrequency.Short : timerMillis;
                Application.SetHighDpiMode(HighDpiMode.SystemAware);
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                Service = new Service(timerMillis);
                Application.Run(Service);
            }
            finally
            {
                //clean shutdown
                if (Service != null)
                {
                    Service.Cleanup();
                }
                mutex.Dispose();
            }
        }