How do I change the current Windows theme programmatically?

前端 未结 12 1943
轻奢々
轻奢々 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 11:55

    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.

    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.

    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).

        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;
        }
    
    0 讨论(0)
  • 2020-12-04 11:55

    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:

    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.

    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 dark or 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:

    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

    b) Returning to the Light – 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.

    0 讨论(0)
  • 2020-12-04 11:55

    For Windows 10 I wrote this simple solution (it can also be used in DSC) in PowerShell

    # Apply your theme
    & "C:\Windows\Resources\Themes\Brand.theme"
    # We need to wait for the theme to be applied
    Start-Sleep -s 5
    # Close the settings window that is opened by the action above
    $window = Get-Process | Where-Object {$_.Name -eq "SystemSettings"}
    Stop-Process -Id $window.Id
    
    0 讨论(0)
  • 2020-12-04 11:57

    It works on Windows 10.

    this is my script. It changes the theme and closes the window. I save it to a batch file and run this patch file from TaskScheduler:

    C:\WINDOWS\system32\rundll32.exe C:\WINDOWS\system32\themecpl.dll,OpenThemeAction C:\Users\xxx\Misc_computer_stuff\themes\my_fav_gr.theme
    
    TIMEOUT 1 & REM Waits 1 seconds before executing the next command
    
    TASKKILL /F /IM systemsettings.exe & close window
    
    exit
    
    0 讨论(0)
  • 2020-12-04 12:01

    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.

    0 讨论(0)
  • 2020-12-04 12:01

    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.

    0 讨论(0)
提交回复
热议问题