How do I change the current Windows theme programmatically?

前端 未结 12 1987
轻奢々
轻奢々 2020-12-04 11:12

I want to allow my users to toggle the current user theme between Aero and Windows Classic(1). Is there a way that I can do this programatically?

I don\'t want to po

12条回答
  •  一个人的身影
    2020-12-04 12:02

    I know this is an old ticket, but somebody asked me how to do this today. So starting from Mike's post above I cleaned things up, added comments, and will post full C# console app code:

    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Globalization;
    using System.IO;
    using System.Linq;
    using System.Runtime.InteropServices;
    using System.Text;
    using System.Threading.Tasks;
    
    using Microsoft.Win32;
    
    namespace Windows7Basic
    {
        class Theming
        {
            /// Handles to Win 32 API
            [DllImport("user32.dll", EntryPoint = "FindWindow")]
            private static extern IntPtr FindWindow(string sClassName, string sAppName);
            [DllImport("user32.dll")]
            private static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
    
            /// Windows Constants
            private const uint WM_CLOSE = 0x10;
    
            private String StartProcessAndWait(string filename, string arguments, int seconds, ref Boolean bExited)
            {
                String msg = String.Empty;
                Process p = new Process();
                p.StartInfo.WindowStyle = ProcessWindowStyle.Minimized;
                p.StartInfo.FileName = filename;
                p.StartInfo.Arguments = arguments;
                p.Start();
    
                bExited = false;
                int counter = 0;
                /// give it "seconds" seconds to run
                while (!bExited && counter < seconds)
                {
                    bExited = p.HasExited;
                    counter++;
                    System.Threading.Thread.Sleep(1000);
                }//while
                if (counter == seconds)
                {
                    msg = "Program did not close in expected time.";
                }//if
    
                return msg;
            }
    
            public Boolean SwitchTheme(string themePath)
            {
                try
                {    
                    //String themePath = System.Environment.GetFolderPath(Environment.SpecialFolder.Windows) + @"\Resources\Ease of Access Themes\basic.theme";
                    /// Set the theme
                    Boolean bExited = false;
                    /// essentially runs the command line:  rundll32.exe %SystemRoot%\system32\shell32.dll,Control_RunDLL %SystemRoot%\system32\desk.cpl desk,@Themes /Action:OpenTheme /file:"%WINDIR%\Resources\Ease of Access Themes\classic.theme"
                    String ThemeOutput = this.StartProcessAndWait("rundll32.exe", System.Environment.GetFolderPath(Environment.SpecialFolder.System) + @"\shell32.dll,Control_RunDLL " + System.Environment.GetFolderPath(Environment.SpecialFolder.System) + "\\desk.cpl desk,@Themes /Action:OpenTheme /file:\"" + themePath + "\"", 30, ref bExited);
    
                    Console.WriteLine(ThemeOutput);
    
                    /// Wait for the theme to be set
                    System.Threading.Thread.Sleep(1000);
    
                    /// Close the Theme UI Window
                    IntPtr hWndTheming = FindWindow("CabinetWClass", null);
                    SendMessage(hWndTheming, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
                }//try
                catch (Exception ex)
                {
                    Console.WriteLine("An exception occured while setting the theme: " + ex.Message);
    
                    return false;
                }//catch
                return true;
            }
    
            public Boolean SwitchToClassicTheme()
            {
                return SwitchTheme(System.Environment.GetFolderPath(Environment.SpecialFolder.Windows) + @"\Resources\Ease of Access Themes\basic.theme");
            }
    
            public Boolean SwitchToAeroTheme()
            {
                return SwitchTheme(System.Environment.GetFolderPath(Environment.SpecialFolder.Windows) + @"\Resources\Themes\aero.theme");
            }
    
            public string GetTheme()
            {
                string RegistryKey = @"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Themes";
                string theme;
                theme = (string)Registry.GetValue(RegistryKey, "CurrentTheme", string.Empty);
                theme = theme.Split('\\').Last().Split('.').First().ToString();
                return theme;
            }
    
            // end of object Theming
        }
    
        //---------------------------------------------------------------------------------------------------------------
    
        class Program
        {
            [DllImport("dwmapi.dll")]
            public static extern IntPtr DwmIsCompositionEnabled(out bool pfEnabled);
    
            /// ;RunProgram("%USERPROFILE%\AppData\Local\Microsoft\Windows\Themes\themeName.theme")      ;For User Themes
            /// RunProgram("%WINDIR%\Resources\Ease of Access Themes\classic.theme")                     ;For Basic Themes
            /// ;RunProgram("%WINDIR%\Resources\Themes\aero.theme")                                      ;For Aero Themes
    
            static void Main(string[] args)
            {
                bool aeroEnabled = false;
                Theming thm = new Theming();
                Console.WriteLine("The current theme is " + thm.GetTheme());
    
                /// The only real difference between Aero and Basic theme is Composition=0 in the [VisualStyles] in Basic (line omitted in Aero)
                /// So test if Composition is enabled
                DwmIsCompositionEnabled(out aeroEnabled);
    
                if (args.Length == 0 || (args.Length > 0 && args[0].ToLower(CultureInfo.InvariantCulture).Equals("basic")))
                {
                    if (aeroEnabled)
                    {
                        Console.WriteLine("Setting to basic...");
                        thm.SwitchToClassicTheme();
                    }//if
                }//if
                else if (args.Length > 0 || args[0].ToLower(CultureInfo.InvariantCulture).Equals("aero"))
                {
                    if (!aeroEnabled)
                    {
                        Console.WriteLine("Setting to aero...");
                        thm.SwitchToAeroTheme();
                    }//if
                }//else if
            }
    
            // end of object Program
        }
    }
    

提交回复
热议问题