Powershell - 让桌面背景更改立即生效

3
我正在运行一个PowerShell脚本,将背景更改为一组特定的颜色。我希望在不重启计算机的情况下完成此操作,但是很遗憾,在Windows 7/8平台上无法立即生效更改。我在网上找到了许多解决方案,但是没有找到适合我的一种。我认为这可能与设置SystemParametersInfo有关,但我不确定。我已经看过一些解决方案并尝试了它们,但我也无法让它们起作用。注册表键更新正常,但更改直到重启后才会生效。以下是我目前拥有的内容,如果有人看到我可以做出不同的建议,我将不胜感激!
backgroundtest.ps1
Add-Type @"
using System;
using System.Runtime.InteropServices;
using Microsoft.Win32;


namespace Background 
{
    public class Setter {
        [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        private static extern int SystemParametersInfo(int uAction, int uParm, string lpvParam, int fuWinIni);
        public const int UpdateIniFile = 0x01;
        public const int SendWinIniChange = 0x02;
        public const int SetDesktopBackground = 20; <# following examples online to set parameters #>

        public static void SetBackground() {
            SystemParametersInfo(SetDesktopBackground, 0, "", UpdateIniFile | SendWinIniChange);
            RegistryKey key = Registry.CurrentUser.OpenSubKey("Control Panel\\Desktop", true);
            key.SetValue(@"WallPaper", 0); <#remove wallpaper#>
            RegistryKey key2 = Registry.CurrentUser.OpenSubKey("Control Panel\\Colors", true);
            key2.SetValue(@"Background", "0 118 163"); <#set background to new color>
            key.Close();
            key2.Close();
         }

    }


}

"@

[Background.Setter]::SetBackground() 

你可以尝试将 SystemParametersInfo 调用移动到更新注册表键之后,而不是之前,因为这可能会导致系统更新其内部状态。 - Jonathan Potter
@JonathanPotter 你好Jonathan,感谢回复。我发现我不需要干预SystemParametersInfo。我需要弄清楚如何使用SetSysColors。现在正在编辑我的问题。 - wheatfairies
如果你想得到一种纯色,你仍然需要使用SystemParametersInfo来清除任何壁纸图像。 - Jonathan Potter
@JonathanPotter 是的,绝对没问题,这段代码可以清除/设置背景。 - wheatfairies
3个回答

7
文档中更改系统颜色的方法是使用SetSysColors函数。
这会向所有顶级窗口发送WM_SYSCOLORCHANGE消息,以通知它们进行更改。
我已更新您的类,将背景清除并将颜色设置为紫色。需要将其复制到PowerShell中。请注意,我声明SetSysColors的方式只能一次更改一种颜色。
public class Setter {
    [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
    private static extern int SystemParametersInfo(int uAction, int uParm, string lpvParam, int fuWinIni);
    [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
    private static extern int SetSysColors(int count, [In] ref int index, [In] ref int colour);

    public const int UpdateIniFile = 0x01;
    public const int SendWinIniChange = 0x02;
    public const int SetDesktopBackground = 20;
    public const int COLOR_BACKGROUND = 1;

    public static void SetBackground() {
        SystemParametersInfo(SetDesktopBackground, 0, "", UpdateIniFile | SendWinIniChange);
        int index = COLOR_BACKGROUND;
        int colour = 0xFF00FF;
        SetSysColors(1, ref index, ref colour);
    }
}

是的,我一直在努力弄清楚这个问题。我需要安装一个外部库才能导入System.Drawing.Color吗?我一直收到一个找不到它的错误。 - wheatfairies
@wheatfairies 我添加了一些代码。它成功地更新了桌面。 - arx
谢谢Arx!那肯定有帮助。我实际上已经想出来了,所以我会发布我的解决方案 :) 大部分功劳归功于这里的链接http://gallery.technet.microsoft.com/scriptcenter/Change-window-borderdesktop-609a6fb2 - wheatfairies

7
昨天是我第一次使用PowerShell,我对自己需要做什么感到非常迷茫。为了将桌面背景更改为纯色,您首先需要删除壁纸,然后可以使用SetSysColors函数立即更改桌面背景。这个链接帮助了我很多。http://gallery.technet.microsoft.com/scriptcenter/Change-window-borderdesktop-609a6fb2 希望这能像它帮助我一样帮助别人。
更新后的代码:
$code = @'
using System;
using System.Drawing;
using System.Runtime.InteropServices;
using Microsoft.Win32;


namespace Background 
{
    public class Setter {
        [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        private static extern int SystemParametersInfo(int uAction, int uParm, string lpvParam, int fuWinIni);
        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError =true)]
        private static extern int SetSysColors(int cElements, int[] lpaElements, int[] lpRgbValues);
        public const int UpdateIniFile = 0x01;
        public const int SendWinIniChange = 0x02;
        public const int SetDesktopBackground = 0x0014;
        public const int COLOR_DESKTOP = 1;
        public int[] first = {COLOR_DESKTOP};


        public static void RemoveWallPaper() {
        SystemParametersInfo( SetDesktopBackground, 0, "", SendWinIniChange | UpdateIniFile );
        RegistryKey key = Registry.CurrentUser.OpenSubKey("Control Panel\\Desktop", true);
        key.SetValue(@"WallPaper", 0);
        key.Close();
        }

        public static void SetBackground(byte r, byte g, byte b) {
            RemoveWallPaper();
            System.Drawing.Color color= System.Drawing.Color.FromArgb(r,g,b);
            int[] elements = {COLOR_DESKTOP};
            int[] colors = { System.Drawing.ColorTranslator.ToWin32(color) }; 
            SetSysColors(elements.Length, elements, colors);
            RegistryKey key = Registry.CurrentUser.OpenSubKey("Control Panel\\Colors", true);
            key.SetValue(@"Background", string.Format("{0} {1} {2}", color.R, color.G, color.B));
            key.Close();

        }

    }


}

'@
Add-Type -TypeDefinition $code -ReferencedAssemblies System.Drawing.dll -PassThru
Function Set-OSCDesktopColor
{
    <# Powershell function to remove desktop background and set background to colors we want #>
    Process
    {
        [Background.Setter]::SetBackground(0,118,163)
        return
    }
}

Set-OSCDesktopColor

4

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接