如何以编程方式更改当前的 Windows 主题?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/546818/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 06:03:34  来源:igfitidea点击:

How do I change the current Windows theme programmatically?

windowsthemes

提问by seanyboy

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

我想让我的用户在Aero和 Windows Classic(1)之间切换当前用户主题。有没有办法以编程方式执行此操作?

I don't want to pop up the "Display properties", and I'm dubious about just changing the registry. (This requires a log out and a log back in for the changes to take effect).

我不想弹出“显示属性”,我怀疑只是更改注册表。(这需要注销并重新登录才能使更改生效)。

Application skinning (using the Codejocklibraries) doesn't work either.

应用程序外观(使用Codejock库)也不起作用。

Is there a way of doing this?

有没有办法做到这一点?

The application is hosted/run on a Windows Server 2008over RDP.

该应用程序通过RDPWindows Server 2008上托管/运行。

(1) The application in question is a hosted "Remote App", and I want users to be able to change the look of the displayed application to match their desktop.

(1) 有问题的应用程序是托管的“远程应用程序”,我希望用户能够更改显示的应用程序的外观以匹配他们的桌面。

回答by Campbell

You can set it using the following command:

您可以使用以下命令设置它:

rundll32.exe %SystemRoot%\system32\shell32.dll,Control_RunDLL %SystemRoot%\system32\desk.cpl desk,@Themes /Action:OpenTheme /file:"C:\Windows\Resources\Themes\aero.theme"

Caveat is that this will show the theme selector dialog. You could kill that dialog straight after.

需要注意的是,这将显示主题选择器对话框。您可以在之后立即终止该对话框。

回答by Jan Goyvaerts

There are certainly good reasons for wanting to change the current theme programmatically. E.g. an automated test tool may need to switch between various themes to make sure the application works correctly with all of them.

想要以编程方式更改当前主题当然有充分的理由。例如,自动化测试工具可能需要在各种主题之间切换,以确保应用程序与所有主题都能正常工作。

As a user, you can change the theme by double-clicking a .themefile in Windwos Explorer and then closing the Control Panel applet that pops up. You can easily do the same from code. The steps below work just fine for me. I've only tested on Windows 7.

作为用户,您可以通过双击.themeWindwos Explorer 中的文件然后关闭弹出的控制面板小程序来更改主题。您可以轻松地从代码中执行相同的操作。下面的步骤对我来说很好。我只在 Windows 7 上测试过。

  1. Use SHGetKnownFolderPath()to get the "Local AppData" folder for the user. Theme files are stored in the Microsoft\Windows\Themessubfolder. Theme files stored there are applied directly, while theme files stored elsewhere are duplicated when you execute them. So it's best to use files from that folder only.
  2. Use ShellExecute()to execute the .themefile you located in step 1.
  3. Wait for the theme to be applied. I simply let my app sleep for 2 seconds.
  4. Call FindWindow('CabinetWClass', 'Personalization')to get the handle of the Control Panel window that popped up when the theme was applied. The "Personalization" caption will likely be different on non-US-English versions of Windows.
  5. Call PostMessage(HWND, WM_CLOSE, 0, 0)to close the Control Panel window.
  1. 使用SHGetKnownFolderPath()获得“本地应用程序数据”文件夹的用户。主题文件存储在Microsoft\Windows\Themes子文件夹中。存储在那里的主题文件是直接应用的,而存储在其他地方的主题文件在您执行时会被复制。所以最好只使用该文件夹中的文件。
  2. 使用ShellExecute()执行.theme你在步骤1中找到的文件。
  3. 等待主题应用。我只是让我的应用程序休眠 2 秒钟。
  4. 调用FindWindow('CabinetWClass', 'Personalization')以获取应用主题时弹出的控制面板窗口的句柄。“个性化”标题在非美国英语版本的 Windows 上可能会有所不同。
  5. 调用PostMessage(HWND, WM_CLOSE, 0, 0)以关闭控制面板窗口。

This isn't a very elegant solution, but it does the job.

这不是一个非常优雅的解决方案,但它可以完成工作。

回答by isopropanol

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:

我知道这是一张旧票,但今天有人问我怎么做。所以从上面 Mike 的帖子开始,我清理了一些东西,添加了评论,并将发布完整的 C# 控制台应用程序代码:

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
    }
}
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
    }
}

回答by Mike de Klerk

In addition of the post of "Jan Goyvaerts": I use SendMessage instead of PostMessage. The difference is that SendMessage waits for the command to be taken in by the window. Meaning that in the SendMessages returns, you know that the theme dialog is closed.

除了“Jan Goyvaerts”的帖子:我使用 SendMessage 而不是 PostMessage。不同之处在于 SendMessage 等待命令被窗口接收。这意味着在 SendMessages 返回时,您知道主题对话框已关闭。

So if you start it with the monstrous (but genious) rundll32.exe method suggested by "Campbell". You should wait a sec before sending WM_CLOSE. Otherwise the theme will not be set and the application closes right away.

因此,如果您使用“Campbell”建议的可怕(但非常巧妙)的 rundll32.exe 方法启动它。您应该在发送 WM_CLOSE 之前等待一秒钟。否则将不会设置主题并且应用程序会立即关闭。

The code snippet below extracts a file from resource (a themepack). Then executes the desk.cpl with rundll32.exe, waits 3 sceonds, then sends WM_CLOSE (0x0010), waits for the command to be process (the time it takes for the theme to be set).

下面的代码片段从资源(主题包)中提取文件。然后用rundll32.exe执行desk.cpl,等待3秒,然后发送WM_CLOSE(0x0010),等待命令被处理(设置主题所需的时间)。

    private Boolean SwitchToClassicTheme()
    {
        //First unpack the theme
        try
        {
            //Extract the theme from the resource
            String ThemePath = System.Environment.GetFolderPath(Environment.SpecialFolder.Windows) + @"\Resources\Themes\ClassicTheme.themepack";
            //WriteFileToCurrentDirectory("ClassicTheme.theme", TabletConfigurator.Resources.ClassicTheme);
            if(File.Exists(ThemePath))
            {
                File.Delete(ThemePath);
            }
            if(File.Exists(ThemePath))
            {
                throw new Exception("The file '" + ThemePath + "' exists and can not be deleted. You can try to delete it manually.");
            }
            using (BinaryWriter sw = new BinaryWriter(new FileStream(ThemePath, FileMode.OpenOrCreate)))
            {
                sw.Write(TabletConfigurator.Resources.ClassicTheme);
                sw.Flush();
                sw.Close();
            }

            if(!File.Exists(ThemePath))
            {
                throw new Exception("The resource theme file could not be extracted");
            }

            //Set the theme file as like a user would have clicked it
            Boolean bTimedOut = false;
            String ThemeOutput = 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 + "\"", ref bTimedOut);

            System.Threading.Thread.Sleep(3000);
            //Wait for the theme to be set
            IntPtr hWndTheming = FindWindow("CabinetWClass", null);
            SendMessage(hWndTheming, (uint)WM_CLOSE, 0, 0);

            //using (Bitmap bm = CaptureScreenShot())
            //{
            //    Boolean PixelIsGray = true;
            //    while (PixelIsGray)
            //    {
            //        System.Drawing.Color pixel = bm.GetPixel(0, 0)
            //    }
            //}

        }
        catch(Exception ex)
        {
            ShowError("An exception occured while setting the theme: " + ex.Message);
            return false;
        }
        return true;
    }

回答by Factor Mystic

I believe the best you can do is open your target .msstyles file (in c:\windows\resources\themes), which will pop up the display properties box. At this point you could use window subclassing to programmatically click the right buttons.

我相信你能做的最好的事情就是打开你的目标 .msstyles 文件(在 中c:\windows\resources\themes),它会弹出显示属性框。此时,您可以使用窗口子类化以编程方式单击右侧按钮。

回答by Cube

The command for newer Windows versions (Windows 8 and 8.1, haven't tried it on W10 yet) is:

较新的 Windows 版本(Windows 8 和 8.1,尚未在 W10 上尝试过)的命令是:

rundll32.exe themecpl.dll,OpenThemeAction %1

or with full paths:

或使用完整路径:

C:\WINDOWS\system32\rundll32.exe C:\WINDOWS\system32\themecpl.dll,OpenThemeAction %LocalAppData%\Microsoft\Windows\Themes\yourtheme.theme

Basically it's the Personalisation CPL"open" command for .theme & .themepack extensions taken from registry...

基本上它是从注册表中获取的 .theme 和 .themepack 扩展的个性化 CPL“打开”命令......

You'll still end up with the Personalisation window beeing open after using this command so to close it down programatically you'll have to use one of the suggested methods mentioned above... (I personally prefer the Powershell script)

使用此命令后,您仍然会打开个性化窗口,因此要以编程方式关闭它,您必须使用上面提到的建议方法之一......(我个人更喜欢 Powershell 脚本)

回答by Daniel Sokolowski

I just realized you can double click the theme and it autoswitches it - much simpler, so just executing the theme works, ex batch file:

我刚刚意识到您可以双击主题并自动切换它 - 简单得多,所以只需执行主题作品,例如批处理文件:

:: Reactivate my theme after an remote desktop session
:: We must select another theme first before we can select ours again and hence re-activate Aero, please wait..."
@echo Off
"C:\Windows\Resources\Themes\aero.theme"
::echo "Simulating a pause while"
ping 127.0.0.1 -n 10 > null && "D:\Users\danielsokolowski\Windows 7 Aero Themes\`danielsokolowski` Theme (without Glass).theme"
::or ping 127.0.0.1 -n 3 > null && "%userprofile%\AppData\Local\Microsoft\Windows\Themes\`danielsokolowski` Theme (without Glass).theme"

回答by joon

I'm not sure if this is a new thing, but you can just double click the .theme file and Windows 10 will apply the theme. Hence, you can do this with PowerShell easily:

我不确定这是否是新事物,但您只需双击 .theme 文件,Windows 10 就会应用该主题。因此,您可以使用 PowerShell 轻松完成此操作:

$Windows10Theme = "C:\Windows\Resources\Themes\aero.theme"
Invoke-Expression $Windows10Theme

回答by Arnold

I have been experimenting about changing the windows theme via command line and I learned that by executing the theme file it is being applied by the Windows 10 as well. So in your batch file, you could use one of the following lines:

我一直在尝试通过命令行更改 Windows 主题,我了解到通过执行主题文件,它也被 Windows 10 应用。因此,在您的批处理文件中,您可以使用以下行之一:

C:\Users\%USERNAME%\AppData\Local\Microsoft\Windows\Themes\Dark_Mode.theme

or

或者

C:\Users\%USERNAME%\AppData\Local\Microsoft\Windows\Themes\Light_Mode.theme

Please note the path to the theme files might be needed to adjust depending on your system user configuration. I strongly advise saving your themes with names excluding spaces as it makes much easier moving forward. Executing such line leaving you with the Settings window opened. To deal with I considered using VBS script instead. Thanks to Patrick Haugh user1390106 there is a much easier way to close the Settings window.

请注意主题文件的路径可能需要根据您的系统用户配置进行调整。我强烈建议使用不包括空格的名称保存您的主题,因为这样可以更轻松地前进。执行这样的行会打开设置窗口。为了处理我考虑使用 VBS 脚本代替。感谢 Patrick Haugh user1390106,有一种更简单的方法可以关闭“设置”窗口。

taskkill /F /IM systemsettings.exe

So the updated version of batch file could look like this:

所以批处理文件的更新版本可能如下所示:

@echo off
if %1 == dark (
REM ================== Go Dark ==================
color 09
echo.
echo   Applying DARK MODE
echo   Windows Theme ...
C:\Users\%USERNAME%\AppData\Local\Microsoft\Windows\Themes\Dark_Mode.theme
timeout /T 1 /nobreak > nul
taskkill /F /IM systemsettings.exe > nul
echo   DONE
) else (
REM ============== Return to Light ==============
color 30
echo.
echo   Applying LIGHT MODE
echo   Windows Theme ...
C:\Users\%USERNAME%\AppData\Local\Microsoft\Windows\Themes\Light_Mode.theme
timeout /T 1 /nobreak > nul
taskkill /F /IM systemsettings.exe > nul
echo   DONE
)
REM ================== Goodbye ==================
echo.
echo   Goodbye
cls
exit

Please note the path to the theme files might be needed to adjust depending on your system user configuration. Save above script with the name theme.bat somewhere in your drive. This batch file taking one parameter which needs to be either darkor any other string. Then you could prepare two shortcuts to this batch file each with one of the following in the box called “Target” on the “Shortcut” tab in its properties:

请注意主题文件的路径可能需要根据您的系统用户配置进行调整。将上述脚本以名称 theme.bat 保存在驱动器中的某个位置。此批处理文件服用这就需要将一个参数,无论是dark或任何其他string。然后,您可以为此批处理文件准备两个快捷方式,每个快捷方式在其属性的“快捷方式”选项卡上名为“目标”的框中具有以下其中一项:

C:\full-path-to-your-batch-file\theme.bat dark

or

或者

C:\full-path-to-your-batch-file\theme.bat light

Please replace “full-path-to-your-batch-file” with actual path to that file. Here are links to the videos showing how this works:

请将“完整路径到您的批处理文件”替换为该文件的实际路径。以下是显示其工作原理的视频链接:

a) Going Dark – https://youtu.be/cBcDNhAmfyM

a) 走向黑暗 – https://youtu.be/cBcDNhAmfyM

b) Returning to the Light – https://youtu.be/2kYJaJHubi4

b) 回归光明 – https://youtu.be/2kYJaJHubi4

Please note that my script in those videos also activating/deactivating the Stylish plug-in for chrome. I have omitted to explain how I accomplished that part as it is not a subject of this article.

请注意,我在这些视频中的脚本还会激活/停用 Chrome 的时尚插件。我省略了解释我是如何完成那部分的,因为它不是本文的主题。

回答by displayname

Okay so here is my take on this - a VB script. It's a bit nasty but the best I could come up with (sadly).

好的,这是我的看法 - 一个VB 脚本。这有点讨厌,但我能想到的最好的(可悲的是)。

For a user that logs in, we simply run ChangeTheme.vbsas the user logs in (e.g. autorun). The script starts desk.cpland passes the required parameters to it as well as the name of the selected theme.

对于登录的用户,我们只需ChangeTheme.vbs在用户登录时运行(例如自动运行)。脚本启动desk.cpl并将所需的参数以及所选主题的名称传递给它。

One can run the script with or without parameters:

可以带或不带参数运行脚本:

> ChangeTheme.vbs
> ChangeTheme.vbs AnyThemeName

The script:

剧本:

' ////////////////////////////////////////////////////////////////////
'
' Changes the theme.
'
' Name:
'     ChangeTheme.vbs
' Parameter 1: 
'     Theme name e.g. aero or anything 
'     located in in C:\Windows\Resources\Themes. 
'     If not present, a default theme will be used.
'
' Example: 
'     Inside a command line run
'     > ChangeTheme.vbs TheThemeName
'
' ////////////////////////////////////////////////////////////////////

If(Wscript.Arguments.Count <= 0) Then
  ' If no parameter was given we set the following theme as default
  selectedTheme = "aero"
Else
  ' Get theme via the first argument  
  selectedTheme = Wscript.Arguments(0)
End If

' Create WScript shell object
Set WshShell = WScript.CreateObject("WScript.Shell")

' Run the command to open the "theme application" (or whatever)
Set process = WshShell.Exec("rundll32.exe %SystemRoot%\system32\shell32.dll,Control_RunDLL %SystemRoot%\system32\desk.cpl desk,@Themes /Action:OpenTheme /file:""C:\Windows\Resources\Themes\" & selectedTheme & ".theme""")

' Wait for the application to start

Wscript.Sleep 250

Success = False
maxTries = 20
tryCount = 0

Do Until Success = True

  Wscript.Sleep 1000

  ' Set focus to our application    
  ' If this fails, or the application loses focus, it won't work!    
  Success = WshShell.AppActivate(process.ProcessId)

  tryCount = tryCount + 1

  If (tryCount >= maxTries) Then
    ' If it does not work after maxTries we give up ..
    MsgBox("Cannot change theme - max tries exceeded ..")
    Exit Do
  End If

Loop

' The crucial part: Send keys ALT + B for applying the theme    
WshShell.Sendkeys "%(B)"

' Send key "escape" to close the window
WshShell.Sendkeys "{ESCAPE}" 

Hope that helps.

希望有帮助。