Change desktop wallpaper using code in .NET

If you want to temporarily set a desktop wallpaper without polluting the Windows settings history, here is a gist I made.

It backups the wallpaper history (stored in the registry) before setting the temporary wallpaper and you can restore it back afterwards.

https://gist.github.com/Drarig29/4aa001074826f7da69b5bb73a83ccd39


Here's a class yanked from an app I wrote a year or two ago:

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(Uri uri, Style style)
    {
        System.IO.Stream s = new System.Net.WebClient().OpenRead(uri.ToString());

        System.Drawing.Image img = System.Drawing.Image.FromStream(s);
        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);
    }
}

I haven't tested it extensively, so use at your own risk.


Bases on this useful answer, I've also made my own app to set wallpaper matching screen resolution.

But the registry settings were wrong. Here are the correct values (tested on Win 7, Win 8.1, Win 10).

if (style == Style.Fill)
{
    key.SetValue(@"WallpaperStyle", 10.ToString());
    key.SetValue(@"TileWallpaper", 0.ToString());
}
if (style == Style.Fit)
{
    key.SetValue(@"WallpaperStyle", 6.ToString());
    key.SetValue(@"TileWallpaper", 0.ToString());
}
if (style == Style.Span) // Windows 8 or newer only!
{
    key.SetValue(@"WallpaperStyle", 22.ToString());
    key.SetValue(@"TileWallpaper", 0.ToString());
}
if (style == Style.Stretch)
{
    key.SetValue(@"WallpaperStyle", 2.ToString());
    key.SetValue(@"TileWallpaper", 0.ToString());
}
if (style == Style.Tile)
{
    key.SetValue(@"WallpaperStyle", 0.ToString());
    key.SetValue(@"TileWallpaper", 1.ToString());
}
if (style == Style.Center)
{
    key.SetValue(@"WallpaperStyle", 0.ToString());
    key.SetValue(@"TileWallpaper", 0.ToString());
}