Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用.NET中的代码更改桌面墙纸_C#_.net_Wpf_Desktop_Wallpaper - Fatal编程技术网

C# 使用.NET中的代码更改桌面墙纸

C# 使用.NET中的代码更改桌面墙纸,c#,.net,wpf,desktop,wallpaper,C#,.net,Wpf,Desktop,Wallpaper,如何使用C代码更改桌面墙纸?这是我一两年前编写的一个应用程序中的一个类: public sealed class Wallpaper { Wallpaper() { } const int SPI_SETDESKWALLPAPER = 20; const int SPIF_UPDATEINIFILE = 0x01; const int SPIF_SENDWININICHANGE = 0x02; [DllImport("user32.dll", Char

如何使用C代码更改桌面墙纸?

这是我一两年前编写的一个应用程序中的一个类:

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

我还没有对它进行过广泛的测试,所以使用它的风险自负。

调整Neal N关于GIF的答案:

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

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

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

/// <summary>
/// Loops numFrames times, animating the desktop background as the given gif.
/// Remember this will sorta bog down your computer, and probably isn't best to be running 24/7.
/// If numFrames is negative this will loop forever
/// </summary>
/// <param name="gifPath">The gif to be animated</param>
/// <param name="transparencyReplace">If the gif has transparency, it will be "replaced" with this color.</param>
/// <param name="framesPerSecond">How many frames to play per second. This is a max: most likely it will be a little slower than this especially at first.</param>
/// <param name="style">Whether to tile, center, or stretch each gif frame as it's played.</param>
/// <param name="numFrames">The number of frames to play. If negative, this method will loop forever.</param>
public static void SetDesktopBackgroundAsGifAsync(string gifPath, System.Drawing.Color transparencyReplace, int framesPerSecond, Style style, int numFrames)
{
    Thread workerThread = new Thread(() => SetDesktopBackgroundAsGif(gifPath, transparencyReplace, framesPerSecond, style, numFrames));
    workerThread.Start();
}

/// <summary>
/// Loops numFrames times, animating the desktop background as the given gif.
/// Remember this will sorta bog down your computer, and probably isn't best to be running 24/7.
/// If num frames is negative this will loop forever. 
//// <summary>
/// <param name="gifPath">The gif to be animated</param>
/// <param name="backgroundImage">Image to render the gif on top of (because of transparency)</param>
/// <param name="framesPerSecond">How many frames to play per second. This is a max: most likely it will be a little slower than this.</param>
/// <param name="style">Whether to tile, center, or stretch each gif frame as it's played.</param>
/// <param name="numFrames">The number of frames to play. If negative, this method will loop forever.</param>
public static void SetDesktopBackgroundAsGifAsync(string gifPath, System.Drawing.Image backgroundImage, int framesPerSecond, Style style, int numFrames)
{
    Thread workerThread = new Thread(() => SetDesktopBackgroundAsGif(gifPath, backgroundImage, framesPerSecond, style, numFrames));
    workerThread.Start();
}

/// <summary>
/// Loops numFrames times, animating the desktop background as the given gif.
/// Remember this will sorta bog down your computer, and probably isn't best to be running 24/7. 
/// if numFrames is negative this will loop forever
/// </summary>
/// <param name="gifPath">The gif to be animated</param>
/// <param name="transparencyReplace">If the gif has transparency, it will be "replaced" with this color.</param>
/// <param name="framesPerSecond">How many frames to play per second. This is a max: most likely it will be a little slower than this.</param>
/// <param name="style">Whether to tile, center, or stretch each gif frame as it's played.</param>
/// <param name="numFrames">The number of frames to play. If negative, this method will loop forever.</param>
public static void SetDesktopBackgroundAsGif(string gifPath, System.Drawing.Color transparencyReplace, int framesPerSecond, Style style, int numFrames)
{
    if (!File.Exists(gifPath))
        throw new Exception("Given gif: '" + gifPath + "' not found");

    FileStream gifFile = new FileStream(gifPath, FileMode.Open);

    GifBitmapDecoder gifDecoder = new GifBitmapDecoder(gifFile, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnLoad);

    if (gifDecoder.Frames.Count == 0)
        throw new Exception("No frames in given gif");

    Bitmap backgroundImage = new Bitmap(gifDecoder.Frames[0].PixelWidth, gifDecoder.Frames[0].PixelHeight, System.Drawing.Imaging.PixelFormat.Format32bppArgb);

    using(Graphics g = Graphics.FromImage(backgroundImage))
    {
        g.FillRectangle(new System.Drawing.SolidBrush(transparencyReplace), 0, 0, gifDecoder.Frames[0].PixelWidth, gifDecoder.Frames[0].PixelHeight);
    }

    gifFile.Close();

    SetDesktopBackgroundAsGif(gifPath, backgroundImage, framesPerSecond, style, numFrames);
}

/// <summary>
/// Loops infinitely, animating the desktop background as the given gif.
/// Remember this will sorta bog down your computer, and probably isn't best to be running 24/7. 
/// </summary>
/// <param name="gifPath">The gif to be animated</param>
/// <param name="backgroundImage">Image to render the gif on top of (because of transparency)</param>
/// <param name="framesPerSecond">How many frames to play per second. This is a max: most likely it will be a little slower than this.</param>
/// <param name="style">Whether to tile, center, or stretch each gif frame as it's played.</param>
/// <param name="numFrames">The number of frames to play. If negative, this method will loop forever.</param>
private static void SetDesktopBackgroundAsGif(string gifPath, System.Drawing.Image backgroundImage, int framesPerSecond, Style style, int numFrames)
{
    if (!File.Exists(gifPath))
        throw new Exception("Given gif: '" + gifPath + "' not found");

    FileStream gifFile = new FileStream(gifPath, FileMode.Open);

    GifBitmapDecoder gifDecoder = new GifBitmapDecoder(gifFile, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnLoad);

    if (gifDecoder.Frames.Count == 0)
        throw new Exception("No frames in given gif");

    Console.WriteLine("Saving frames to temporary files:");

    int numFramesSoFar = 0;

    for (int i = 0; i < gifDecoder.Frames.Count; i++)
    {
        BitmapFrame gifFrame = gifDecoder.Frames[i];
        PngBitmapEncoder pngEncoder = new PngBitmapEncoder();
        pngEncoder.Frames.Add(gifFrame);
        MemoryStream pngStream = new MemoryStream();
        pngEncoder.Save(pngStream);
        Image frameImage = Image.FromStream(pngStream);
        Bitmap bmp = new Bitmap(frameImage.Width, frameImage.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
        using (Graphics g = Graphics.FromImage(bmp))
        {
            g.DrawImage(backgroundImage, 0, 0);
            g.DrawImageUnscaled(frameImage, 0, 0);
        }
        string tempPath = Path.Combine(Path.GetTempPath(), gifPath + i + ".bmp");
        bmp.Save(tempPath, System.Drawing.Imaging.ImageFormat.Bmp);

        Console.WriteLine("Saved frame " + i);

        numFramesSoFar++;

        if (numFrames >= 0 && numFramesSoFar >= numFrames) break;
    }

    Console.WriteLine("Setting frames to desktop background at about " + framesPerSecond + " FPS");

    // 1.0/... to convert to seconds per frame (instead of frames per second)
    // * 1000 to convert to milliseconds per frame
    // * 1000 to convert to microseconds per frame
    // * 10 to convert to 0.1s of microseconds per frame = 100s of nanoseconds per frame
    long ticksBetweenFrames = (long)Math.Round(1.0 / framesPerSecond) * 1000*1000*10;

    Stopwatch timer = new Stopwatch();
    timer.Start();

    numFramesSoFar = 0;

    while(numFrames < 0 || numFramesSoFar < numFrames)
    {
        for (int i = 0; i < gifDecoder.Frames.Count; i++)
        {
            // Sleep until we're at the desired frame rate, if needed.
            if(ticksBetweenFrames > timer.ElapsedTicks)
                Thread.Sleep(new TimeSpan(Math.Max(0, ticksBetweenFrames - timer.ElapsedTicks)));

            timer.Restart();

            // From http://stackoverflow.com/a/1061682/2924421

            string filePath = Path.Combine(Path.GetTempPath(), "wallpaper" + i + ".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,
                filePath,
                SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE);

            numFramesSoFar++;

            if (numFrames >= 0 && numFramesSoFar >= numFrames) break;
        }
    }

    gifFile.Close();
}
最后,右键单击项目,添加引用,并(在程序集和框架中)添加演示核心、System.Xaml和WindowsBase

然后右键单击您的项目并进入属性,并确保目标框架是.NETFramework4.5。如果更改此选项,您可能需要重新启动Visual Studio。

基于此,我还设置了与壁纸匹配的屏幕分辨率

但是注册表设置是错误的。以下是正确的值(在Win 7、Win 8.1和Win 10上测试)

如果您在c#中使用UWP,以下是我找到的代码


如果你想临时设置桌面壁纸而不污染Windows设置历史记录,下面是我的要点

它会在设置临时墙纸之前备份(存储在注册表中),然后您可以将其还原回来


不确定windows是否支持jpeg作为壁纸。。。在设置为壁纸之前,它会将其他图像转换为bmp(如果我错了,请纠正我)。如果是这种情况,您必须在代码中进行转换,我已经将此用于JPEG格式了。仅仅因为它在上面的代码中被称为bmp并不限制它。它可能适用于PNG和GIF以及其他,但我还没有验证。@Nelin这很好,但是如果要添加一个复选框“空白墙纸”将墙纸设置为黑色呢!仅供参考:此代码不适用于PNG。我必须先手动转换成BMP。哇!这是完全可行的,它支持JPG。。。干得真不错。恭喜你,这当然会让机器陷入困境。有一个阻塞无限循环,调用
Thread.Sleep
随意抛出。有更好的方法等待时间的流逝。不,我认为这更多地与调用SystemParametersInfo有关(比如,每秒10次)。桌面不应该像那样刷新。“explorer”的cpu使用率从0%提高到6-12%,只要运行一个调用此方法的程序就可以证明这一点。不过,我调整了我的答案,添加了异步方法并对线程进行了调用。无睡眠垃圾邮件(仅在需要时发生)。还有其他明显的问题吗?我考虑过用另一种方法调整它来停止线程,但对于一种方法来说,这似乎太过分了,而这种方法一开始可能不是很好的做法。经过再三考虑,我添加了一个numFrames参数,它指定了在该方法停止之前要设置动画的帧数。如果是负数,它将永远消失。等待并倾听什么?为什么要使用(number).ToString()?“为什么不”(数字)?当然可以。这是一个概念问题——我这样写是因为其他人这样做了。
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Media;
using System.Windows.Media.Imaging;
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());
}
using Windows.System.UserProfile; 

// Pass in a relative path to a file inside the local appdata folder 
async Task<bool> SetWallpaperAsync(string localAppDataFileName) 
{ 
   bool success = false; 
   if (UserProfilePersonalizationSettings.IsSupported())       
   {
       var uri = new Uri("ms-appx:///Local/" + localAppDataFileName);
       StorageFile file = await StorageFile.GetFileFromApplicationUriAsync(uri);
       UserProfilePersonalizationSettings profileSettings = UserProfilePersonalizationSettings.Current;
       success = await profileSettings.TrySetWallpaperImageAsync(file);
   }
}
StorageFile file = await ApplicationData.Current.LocalFolder.CreateFileAsync("file.png", CreationCollisionOption.ReplaceExisting);
bool success = false;
UserProfilePersonalizationSettings profileSettings = UserProfilePersonalizationSettings.Current;
success = await profileSettings.TrySetWallpaperImageAsync(file);