Как программно изменить обои для рабочего стола Windows? - PullRequest
12 голосов
/ 07 декабря 2011

Я бы хотел установить обои для Windows XP, используя C #.Я разработал код, чтобы он отлично работал в Windows 7, но, видимо, для XP это не то же самое.Я добавляю эти обои в качестве ресурса, устанавливаю их действие компиляции как Content и Always copy.Любопытно, что он устанавливает правильное имя обоев в диалоге свойств рабочего стола.Однако обои не установлены.Мой код выглядит так:

public sealed class Wallpaper
{
    Wallpaper() { }

    const int SPI_SETDESKWALLPAPER = 20;
    const int SPIF_UPDATEINIFILE = 0x01;
    const int SPIF_SENDWININICHANGE = 0x02;

    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    static extern int SystemParametersInfo(int uAction, int uParam, string lpvParam, int fuWinIni);

    public enum Style : int
    {
        Tiled,
        Centered,
        Stretched
    }

    public static void Set(string wpaper, Style style)
    {
        RegistryKey key = Registry.CurrentUser.OpenSubKey(@"Control Panel\Desktop", true);
        if (style == Style.Stretched)
        {
            key.SetValue(@"WallpaperStyle", 2.ToString());
            key.SetValue(@"TileWallpaper", 0.ToString());
        }

        if (style == Style.Centered)
        {
            key.SetValue(@"WallpaperStyle", 1.ToString());
            key.SetValue(@"TileWallpaper", 0.ToString());
        }

        if (style == Style.Tiled)
        {
            key.SetValue(@"WallpaperStyle", 1.ToString());
            key.SetValue(@"TileWallpaper", 1.ToString());
        }

        string tempPath = "Resources\\"+wpaper;
        SystemParametersInfo(SPI_SETDESKWALLPAPER,
            0,
            tempPath,
            SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE);
    }
}

При вызове Wallpaper.Set ("wpapername") он получает обои из ресурсов проекта.Это работает на Win7, но не на WinXP.Я что-то не так делаю?

Ответы [ 2 ]

12 голосов
/ 12 декабря 2011

Ну, это немного неловко, но я отвечу на свой вопрос тем, что нашел.

Мне пришлось повторно использовать больше кода из принятого ответа здесь . В основном проблема в XP заключалась в том, что ей нужно было использовать файл bmp, поэтому мне удалось преобразовать ресурс проекта в файл bmp, используя предыдущий пример, и немного подправить. Метод Set отлично работает следующим образом:

public static void Set(string wpaper, Style style)
{
    using(System.Drawing.Image img = System.Drawing.Image.FromFile(Path.GetFullPath(wpaper)))
    {
        string tempPath = Path.Combine(Path.GetTempPath(), "wallpaper.bmp");

        img.Save(tempPath, System.Drawing.Imaging.ImageFormat.Bmp);

    }

    RegistryKey key = Registry.CurrentUser.OpenSubKey(@"Control Panel\Desktop", true);

    if (style == Style.Stretched)
    {
        key.SetValue(@"WallpaperStyle", 2.ToString());

        key.SetValue(@"TileWallpaper", 0.ToString());

    }

    if (style == Style.Centered)
    {
        key.SetValue(@"WallpaperStyle", 1.ToString());

        key.SetValue(@"TileWallpaper", 0.ToString());

    }

    if (style == Style.Tiled)
    {
        key.SetValue(@"WallpaperStyle", 1.ToString());

        key.SetValue(@"TileWallpaper", 1.ToString());

    }

    SystemParametersInfo(SPI_SETDESKWALLPAPER,
        0,
        tempPath,
        SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE);

}

Важная часть находится в третьей строке этого кода (System.Drawing.Image.FromFile(Path.GetFullPath(wpaper));).

8 голосов
/ 22 марта 2016

Для хорошего надежного решения.

Добавьте следующий класс в ваш проект

using Microsoft.Win32;
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Runtime.InteropServices;

namespace XXXNAMESPACEXXX
{
    public class Wallpaper
    {
        public enum Style : int
        {
            Tiled,
            Centered,
            Stretched
        }

        [DllImport("user32.dll")]
        public static extern Int32 SystemParametersInfo(UInt32 action, UInt32 uParam, String vParam, UInt32 winIni);

        public static readonly UInt32 SPI_SETDESKWALLPAPER = 0x14;
        public static readonly UInt32 SPIF_UPDATEINIFILE = 0x01;
        public static readonly UInt32 SPIF_SENDWININICHANGE = 0x02;

        public static bool Set(string filePath, Style style)
        {
            bool Success = false;
            try
            {
                Image i = System.Drawing.Image.FromFile(Path.GetFullPath(filePath));

                Set(i, style);

                Success = true;

            }
            catch //(Exception ex)
            {
                //ex.HandleException();
            }
            return Success;
        }

        public static bool Set(Image image, Style style)
        {
            bool Success = false;
            try
            {
                string TempPath = Path.Combine(Path.GetTempPath(), "wallpaper.bmp");

                image.Save(TempPath, ImageFormat.Bmp);

                RegistryKey key = Registry.CurrentUser.OpenSubKey(@"Control Panel\Desktop", true);

                switch (style)
                {
                    case Style.Stretched:
                        key.SetValue(@"WallpaperStyle", 2.ToString());

                        key.SetValue(@"TileWallpaper", 0.ToString());

                        break;

                    case Style.Centered:
                        key.SetValue(@"WallpaperStyle", 1.ToString());

                        key.SetValue(@"TileWallpaper", 0.ToString());

                        break;

                    default:
                    case Style.Tiled:
                        key.SetValue(@"WallpaperStyle", 1.ToString());

                        key.SetValue(@"TileWallpaper", 1.ToString());

                        break;

                }

                SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, TempPath, SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE);

                Success = true;

            }
            catch //(Exception ex)
            {
                //ex.HandleException();
            }
            return Success;
        }

    }

}

Примечание. Замените XXXNAMESPACEXXX на пространство имен по умолчанию вашего проекта.

Windows 7

Тогда его можно использовать следующим образом:

string FilePath = TxtFilePath.Text;

Wallpaper.Set(FilePath, Wallpaper.Style.Centered);

Его также можно использовать так:

if(Wallpaper.Set(FilePath, Wallpaper.Style.Centered))
{
    MessageBox.Show("Your wallpaper has been set to " + FilePath);

}
else
{
    MessageBox.Show("There was a problem setting the wallpaper.");

}

Это проверенная работа на Windows XP, 7, 8, 8.1 и Windows 10.

Примечание Следует иметь в виду, что этот метод будет Обойти любые ограничения безопасности обоев рабочего стола, применяемые сетевым администратором.

...