我自己用这些代码做的小app如下:

最新版本已经改成了服务的方式,也可以选择性添加系统的右键菜单,并且我自己使用的源码库已经开源到了nuget,大家可以直接拿来做二次开发,

新版的下载地址为:https://www.zhaimaojun.cn/P/桌面壁纸管理器/

开源库为(可以直接在vs的nuget包管理中搜索到):https://www.nuget.org/packages/WindowsAPI/

第一种,user32.dll

/// <summary>
/// 调用外部切换壁纸的方法
/// </summary>
/// <param name="uAction"></param>
/// <param name="uParam"></param>
/// <param name="lpvParam"></param>
/// <param name="fuWinIni"></param>
/// <returns></returns>
[DllImport("user32.dll", EntryPoint = "SystemParametersInfo")]
public static extern int SystemParametersInfo(int uAction, int uParam, string lpvParam, int fuWinIni);

就是一种很常用,好像兼容性最好的办法吧,但是,使用的局限性很大,多显示器情况下会导致所有显示器使用相同的壁纸!而且无法区分多个显示器

第二种,IActiveDesktop

public class ActiveDesktopCom
{
/// <summary>
/// 壁纸的显示方式
/// </summary>
public enum WPSTYLE
{
/// <summary>
/// 居中
/// </summary>
CENTER = 0,
/// <summary>
/// 平铺
/// </summary>
TILE = 1,
/// <summary>
/// 拉伸
/// </summary>
STRETCH = 2,
/// <summary>
/// 适应
/// </summary>
adapt = 3,
/// <summary>
/// 填充
/// </summary>
FILL = 4,
/// <summary>
/// 跨区
/// </summary>
Transregional = 5,
} struct WALLPAPEROPT
{
public int dwSize;
public WPSTYLE dwStyle;
} struct COMPONENTSOPT
{
public int dwSize;
[MarshalAs(UnmanagedType.Bool)]
public bool fEnableComponents;
[MarshalAs(UnmanagedType.Bool)]
public bool fActiveDesktop;
} struct COMPPOS
{
public const int COMPONENT_TOP = 0x3FFFFFFF;
public const int COMPONENT_DEFAULT_LEFT = 0xFFFF;
public const int COMPONENT_DEFAULT_TOP = 0xFFFF; public int dwSize;
public int iLeft;
public int iTop;
public int dwWidth;
public int dwHeight;
public int izIndex;
[MarshalAs(UnmanagedType.Bool)]
public bool fCanResize;
[MarshalAs(UnmanagedType.Bool)]
public bool fCanResizeX;
[MarshalAs(UnmanagedType.Bool)]
public bool fCanResizeY;
public int iPreferredLeftPercent;
public int iPreferredTopPercent;
} [Flags]
enum ITEMSTATE
{
NORMAL = 0x00000001,
FULLSCREEN = 00000002,
SPLIT = 0x00000004,
VALIDSIZESTATEBITS = NORMAL | SPLIT | FULLSCREEN,
VALIDSTATEBITS = NORMAL | SPLIT | FULLSCREEN | unchecked((int)0x80000000) | 0x40000000
} struct COMPSTATEINFO
{
public int dwSize;
public int iLeft;
public int iTop;
public int dwWidth;
public int dwHeight;
public int dwItemState;
} enum COMP_TYPE
{
HTMLDOC = 0,
PICTURE = 1,
WEBSITE = 2,
CONTROL = 3,
CFHTML = 4,
MAX = 4
} [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
struct COMPONENT
{
private const int INTERNET_MAX_URL_LENGTH = 2084; // =
// INTERNET_MAX_SCHEME_LENGTH (32) + "://\0".Length +
// INTERNET_MAX_PATH_LENGTH (2048) public int dwSize;
public int dwID;
public COMP_TYPE iComponentType;
[MarshalAs(UnmanagedType.Bool)]
public bool fChecked;
[MarshalAs(UnmanagedType.Bool)]
public bool fDirty;
[MarshalAs(UnmanagedType.Bool)]
public bool fNoScroll;
public COMPPOS cpPos;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string wszFriendlyName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = INTERNET_MAX_URL_LENGTH)]
public string wszSource;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = INTERNET_MAX_URL_LENGTH)]
public string wszSubscribedURL; #if AD_IE5
public int dwCurItemState;
public COMPSTATEINFO csiOriginal;
public COMPSTATEINFO csiRestored;
#endif
} enum DTI_ADTIWUI
{
DTI_ADDUI_DEFAULT = 0x00000000,
DTI_ADDUI_DISPSUBWIZARD = 0x00000001,
DTI_ADDUI_POSITIONITEM = 0x00000002,
} [Flags]
enum AD_APPLY
{
SAVE = 0x00000001,
HTMLGEN = 0x00000002,
REFRESH = 0x00000004,
ALL = SAVE | HTMLGEN | REFRESH,
FORCE = 0x00000008,
BUFFERED_REFRESH = 0x00000010,
DYNAMICREFRESH = 0x00000020
} [Flags]
enum COMP_ELEM
{
TYPE = 0x00000001,
CHECKED = 0x00000002,
DIRTY = 0x00000004,
NOSCROLL = 0x00000008,
POS_LEFT = 0x00000010,
POS_TOP = 0x00000020,
SIZE_WIDTH = 0x00000040,
SIZE_HEIGHT = 0x00000080,
POS_ZINDEX = 0x00000100,
SOURCE = 0x00000200,
FRIENDLYNAME = 0x00000400,
SUBSCRIBEDURL = 0x00000800,
ORIGINAL_CSI = 0x00001000,
RESTORED_CSI = 0x00002000,
CURITEMSTATE = 0x00004000,
ALL = TYPE | CHECKED | DIRTY | NOSCROLL | POS_LEFT | SIZE_WIDTH |
SIZE_HEIGHT | POS_ZINDEX | SOURCE |
FRIENDLYNAME | POS_TOP | SUBSCRIBEDURL | ORIGINAL_CSI |
RESTORED_CSI | CURITEMSTATE
} [Flags]
enum ADDURL
{
SILENT = 0x0001
} [
ComImport(),
Guid("F490EB00-1240-11D1-9888-006097DEACF9"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)
]
interface IActiveDesktop
{
void ApplyChanges(AD_APPLY dwFlags);
void GetWallpaper([MarshalAs(UnmanagedType.LPWStr)] System.Text.StringBuilder pwszWallpaper, int cchWallpaper, int dwReserved);
void SetWallpaper([MarshalAs(UnmanagedType.LPWStr)] string pwszWallpaper, int dwReserved);
void GetWallpaperOptions(ref WALLPAPEROPT pwpo, int dwReserved);
void SetWallpaperOptions([In] ref WALLPAPEROPT pwpo, int dwReserved);
void GetPattern([MarshalAs(UnmanagedType.LPWStr)] System.Text.StringBuilder pwszPattern, int cchPattern, int dwReserved);
void SetPattern([MarshalAs(UnmanagedType.LPWStr)] string pwszPattern, int dwReserved);
void GetDesktopItemOptions(ref COMPONENTSOPT pco, int dwReserved);
void SetDesktopItemOptions([In] ref COMPONENTSOPT pco, int dwReserved);
void AddDesktopItem([In] ref COMPONENT pcomp, int dwReserved);
void AddDesktopItemWithUI(IntPtr hwnd, [In] ref COMPONENT pcomp, DTI_ADTIWUI dwFlags);
void ModifyDesktopItem([In] ref COMPONENT pcomp, COMP_ELEM dwFlags);
void RemoveDesktopItem([In] ref COMPONENT pcomp, int dwReserved);
void GetDesktopItemCount(out int lpiCount, int dwReserved);
void GetDesktopItem(int nComponent, ref COMPONENT pcomp, int dwReserved);
void GetDesktopItemByID(IntPtr dwID, ref COMPONENT pcomp, int dwReserved);
void GenerateDesktopItemHtml([MarshalAs(UnmanagedType.LPWStr)] string pwszFileName, [In] ref COMPONENT pcomp, int dwReserved);
void AddUrl(IntPtr hwnd, [MarshalAs(UnmanagedType.LPWStr)] string pszSource, [In] ref COMPONENT pcomp, ADDURL dwFlags);
void GetDesktopItemBySource([MarshalAs(UnmanagedType.LPWStr)] string pwszSource, ref COMPONENT pcomp, int dwReserved);
} [
ComImport(),
Guid("75048700-EF1F-11D0-9888-006097DEACF9")
]
class ActiveDesktop /* : IActiveDesktop */ { }
public class OLE32DLL
{
[DllImport("ole32.dll", SetLastError = true)]
public static extern int CoUninitialize(); [DllImport("ole32.dll", SetLastError = true)]
public static extern int CoInitialize(int pvReserved); [DllImport("ole32.dll", CharSet = CharSet.Unicode)]
public static extern int CLSIDFromString(string lpsz, out Guid pclsid); [DllImport("ole32.dll", ExactSpelling = true, PreserveSig = false)]
[return: MarshalAs(UnmanagedType.Interface)]
public static extern object CoCreateInstance(
[In, MarshalAs(UnmanagedType.LPStruct)] Guid rclsid,
int pUnkOuter,
int dwClsContext,
[In, MarshalAs(UnmanagedType.LPStruct)] Guid riid
);
}
/// <summary>
/// 兼容win7版本以前版本系统的修改壁纸
/// </summary>
/// <param name="filename"></param>
/// <returns></returns>
public static bool SetActiveDesktop(string filename, WPSTYLE dwstyle = WPSTYLE.FILL)
{
try
{
const int NULL = 0;
const int S_OK = 0;
const int CLSCTX_ALL = 23; Guid IID_IActiveDesktop = new Guid("F490EB00-1240-11D1-9888-006097DEACF9");
Guid CLSID_ActiveDesktop = new Guid("75048700-EF1F-11D0-9888-006097DEACF9"); if (System.Threading.Thread.CurrentThread.GetApartmentState() != System.Threading.ApartmentState.STA && OLE32DLL.CoInitialize(NULL) < S_OK)
throw new Exception("Failed to initialize COM library.");
//object ppvObject = CoCreateInstance(CLSID_ActiveDesktop, NULL, CLSCTX_ALL, IID_IActiveDesktop);
//ActiveDesktop ad = new ActiveDesktop();
object ad = OLE32DLL.CoCreateInstance(CLSID_ActiveDesktop, NULL, CLSCTX_ALL, IID_IActiveDesktop);
IActiveDesktop iad = (IActiveDesktop)ad;
if (iad != null)
{
//WPSTYLE_CENTER 居中 0
//WPSTYLE_TILE 平铺 1
//WPSTYLE_STRETCH 拉伸 2
//WPSTYLE dwstyle = WPSTYLE.FILL;//这里调整显示背景图片样式
WALLPAPEROPT wp = new WALLPAPEROPT();
wp.dwSize = System.Runtime.InteropServices.Marshal.SizeOf(wp);
wp.dwStyle = dwstyle;
iad.SetWallpaperOptions(ref wp, 0);
iad.SetWallpaper(filename, 0);
iad.ApplyChanges(AD_APPLY.ALL);//AD_APPLY.ALL);
//System.Runtime.InteropServices.Marshal.ReleaseComObject(ad);
//ad = null;
}
OLE32DLL.CoUninitialize();
return true;
}
catch
{
return false;
}
}
}

以上代码也是我从网上流传的代码中复制到的,但是网上流传的代码中其中有一部分代码是有问题的:

ActiveDesktop ad = new ActiveDesktop();

就是这里,这个代码不可运行,因为这种接口中IActiveDesktop对象不能通过类型强转得到,因为ActiveDesktop实例本身就不是通过new方式得到的,而我的代码中已经将这个错误进行了修改,并且win10系统中已经确认运行无误。

第三种,IDesktopWallpaper也是一种Com接口(只支持win8以上系统,且支持多显示器独立设置壁纸)

/// <summary>
/// 使用IDesktopWallpaper方式切换壁纸的方法
/// </summary>
public class DesktopWallpaperCom
{
[ComImport]
[Guid("B92B56A9-8B55-4E14-9A89-0199BBB6F93B")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IDesktopWallpaper
{
void SetWallpaper([MarshalAs(UnmanagedType.LPWStr)] string monitorID, [MarshalAs(UnmanagedType.LPWStr)] string wallpaper); [return: MarshalAs(UnmanagedType.LPWStr)]
string GetWallpaper([MarshalAs(UnmanagedType.LPWStr)] string monitorID); [return: MarshalAs(UnmanagedType.LPWStr)]
string GetMonitorDevicePathAt(uint monitorIndex); [return: MarshalAs(UnmanagedType.U4)]
uint GetMonitorDevicePathCount(); [return: MarshalAs(UnmanagedType.Struct)]
Rect GetMonitorRECT([MarshalAs(UnmanagedType.LPWStr)] string monitorID); void SetBackgroundColor([MarshalAs(UnmanagedType.U4)] uint color); [return: MarshalAs(UnmanagedType.U4)]
uint GetBackgroundColor(); void SetPosition([MarshalAs(UnmanagedType.I4)] DesktopWallpaperPosition position); [return: MarshalAs(UnmanagedType.I4)]
DesktopWallpaperPosition GetPosition(); void SetSlideshow(IntPtr items); IntPtr GetSlideshow(); void SetSlideshowOptions(DesktopSlideshowDirection options, uint slideshowTick); void GetSlideshowOptions(out DesktopSlideshowDirection options, out uint slideshowTick); void AdvanceSlideshow([MarshalAs(UnmanagedType.LPWStr)] string monitorID, [MarshalAs(UnmanagedType.I4)] DesktopSlideshowDirection direction); DesktopSlideshowDirection GetStatus(); bool Enable();
} [ComImport]
[Guid("C2CF3110-460E-4fc1-B9D0-8A1C0C9CC4BD")]
public class DesktopWallpaper
{
} [Flags]
public enum DesktopSlideshowOptions
{
None = 0,
ShuffleImages = 0x01
} [Flags]
public enum DesktopSlideshowState
{
None = 0,
Enabled = 0x01,
Slideshow = 0x02,
DisabledByRemoteSession = 0x04
} public enum DesktopSlideshowDirection
{
Forward = 0,
Backward = 1
} public enum DesktopWallpaperPosition
{
Center = 0,
Tile = 1,
Stretch = 2,
Fit = 3,
Fill = 4,
Span = 5,
} [StructLayout(LayoutKind.Sequential)]
public struct Rect
{
public int Left;
public int Top;
public int Right;
public int Bottom;
}
/// <summary>
/// 获取所有的显示器的ID,用于在设置壁纸中用到的显示器的id
/// </summary>
/// <returns></returns>
public static string[] GetDeskMonitorIds()
{
try
{
DesktopWallpaper ad = new DesktopWallpaper();
IDesktopWallpaper iad = (IDesktopWallpaper)ad;
List<string> mids = new List<string>();
if (iad != null)
{
for (uint i = 0; i < iad.GetMonitorDevicePathCount(); i++)
{
mids.Add(iad.GetMonitorDevicePathAt(i));
}
}
System.Runtime.InteropServices.Marshal.ReleaseComObject(ad);
ad = null;
return mids.ToArray();
}
catch
{
return null;
}
}
/// <summary>
/// 新版的win8以上版本调用修改桌面的方法
/// </summary>
/// <param name="filename"></param>
/// <returns></returns>
public static bool SetDesktopWallpaper(string filename, string mid = null)
{
try
{
DesktopWallpaper ad = new DesktopWallpaper();
IDesktopWallpaper iad = (IDesktopWallpaper)ad;
if (iad != null)
{
iad.SetWallpaper(mid ?? string.Empty, filename);
}
System.Runtime.InteropServices.Marshal.ReleaseComObject(ad);
ad = null;
return true;
}
catch
{
return false;
}
}
}

这是win8系统以上才支持的一种桌面壁纸切换方法,可以支持多显示器独立进行壁纸的设置

最后放上我自己做的壁纸切换工具,可以自适应切换壁纸的方式,且支持多显示器壁纸切换管理和收藏,还有可以添加自动切换壁纸的系统任务,其中的有个vbs脚本是用于壁纸切换的,杀软一般都会报毒,但是要是文件没了就无法切换壁纸了。

下载地址是:https://www.zhaimaojun.cn/P/%e6%a1%8c%e9%9d%a2%e5%a3%81%e7%ba%b8%e7%ae%a1%e7%90%86%e5%99%a8/

以上。

windows系统桌面壁纸切换的三种csharp办法,兼容win10及旧版,还有一个现成桌面小程序的更多相关文章

  1. Windows系统搭建Redis集群三种模式(零坑、最新版)

    目录 主从复制 修改配置文件 启动各节点 验证 哨兵模式 修改配置文件 启动实例 验证 集群模式 修改配置文件 启动实例 验证 主从复制 新建以下三个目录,用来部署一主二从 redis 的安装在另外一 ...

  2. 【百度地图API】关于如何进行城市切换的三种方式

    原文:[百度地图API]关于如何进行城市切换的三种方式 摘要:本文介绍了三种切换城市的方式:查询城市.城市列表和显示城市轮廓. ------------------------------------ ...

  3. 转:extjs 添加loading状态的三种解决办法:

    extjs 添加loading状态的三种解决办法: 方法一: //materialGrid 指需要显示loading状态的控件id var o=Ext.getCmp('materialGrid'); ...

  4. js实现选项卡切换的三种方式

    前两种主要实现一个选项卡的切换,第三种使用闭包看书,构造函数实现多个选项卡的切换: 1.第一种实现实现效果为: 实现代码为: <!doctype html> <!DOCTYPE ht ...

  5. CSS实现导航条Tab切换的三种方法

    前面的话   导航条Tab在页面中非常常见,本文说详细介绍CSS实现导航条Tab的三种方法 布局   根据上图所示,先规定几个定义,上图的模块整体叫做导航,由导航标题和导航内容组成.要实现上图所示的布 ...

  6. linux系统中,文件的三种特殊权限

    背景介绍 在linux系统中,我们熟知有rwx三种权限,对应所有者,同组用户,其他用户三种用户的权限,一共9个位来指定一个文件的权限情况,通过chmod xxx 来更改权限属性,其中xxx是已八进制表 ...

  7. Windows下图文详解PHP三种运行方式(php_mod、cgi、fastcgi)

    PHP能不能成功的在Apache服务器上运行,就看我们如何去配置PHP的运行方式.PHP运行目前为止主要有三种方式: a.以模块加载的方式运行,初学者可能不容易理解,其实就是将PHP集成到Apache ...

  8. vue后台管理项目中菜单栏切换的三种方法

    第一种方法:vue嵌套路由(二) <el-menu :default-active="defaultActive" style="min-height: 100%; ...

  9. 总是弹出visual studio 实时调试器 三种解决办法

    最近服务器老是弹出visual studio 实时调试器很是郁闷呀.关还关不掉.怎么解决呢 ,现像如下图所示: 下面我们一起来分析一下这种情况的原因: 弹出应用程序: Visual Studio 实时 ...

  10. 电脑开机失败提示"用户配置文件服务登录失败"的三种解决办法

    最近遇到这样一个怪现象,就是每次打开电脑输入密码,突然提示"User Profile Service 服务未能登录,无法加载用户配置文件",然后就没办法正常开机了,为什么会这样呢? ...

随机推荐

  1. KingbaseES V8R3 集群运维系列之 -- network_rewind.sh磁盘检测功能详解

    ​ 案例说明: 在KingbaseES V8R3集群,network_rewind.sh用于当节点数据库服务down时,实现数据库服务的自动恢复功能.在network_rewind.sh执行时,会对数 ...

  2. 【LGR-065】洛谷11月月赛 III Div.1

    T1,T2,T3,T4 T1 基础博弈练习题 分析 首先区间长度为1的情况特判,偶数必胜,奇数必败 考虑倒推,如果最后一个位置为偶数那么该位置为必败局面,否则为必胜局面 因为先手到这个位置要减去1就会 ...

  3. USACO 4.1

    目录 洛谷 2737 麦香牛块 分析 代码 洛谷 2738 篱笆回路 分析 代码 麦香牛块洛谷传送门,麦香牛块USACO传送门,篱笆回路洛谷传送门,篱笆回路USACO传送门 洛谷 2737 麦香牛块 ...

  4. OpenHarmony社区运营报告(2023年12月)

      • 截至2023年12月22日,OpenAtom OpenHarmony(简称"OpenHarmony")社区累计超过6700名贡献者,产生26.9万多个PR,2.4万多个St ...

  5. Spring源码 20 手写模拟

    项目地址 https://gitee.com/liao-hang/hand-write-spring.git 模拟 Spring 注解 自动装配 Autowired @Target(ElementTy ...

  6. 手工安装部署openGauss3.0一主一备(非om工具安装)

    手工安装部署 openGauss3.0 一主一备(非 om 工具安装) 本文出处:https://www.modb.pro/db/425385 一.操作系统配置(centos7.6) 1.关闭防火墙 ...

  7. MindSpore编译构建后Vmap模块的RuntimeError问题

    技术背景 这篇文章来源于MindSpore仓库中的一个Issue,简单描述问题就是,如果你用MindSpore开发了一个python软件供别人使用,那么很有可能涉及到编译构建的问题.但是如果直接使用编 ...

  8. 直播预告丨Hello HarmonyOS进阶课程第三课——游戏开发实践

    为了帮助初识HarmonyOS的开发者快速入门,我们曾推出Hello HarmonyOS系列一共5期课程,从最基础的配置IDE和创建Hello World开始,详细介绍HarmonyOS基础.开发环境 ...

  9. 直播预告丨Hello HarmonyOS进阶课程第二课——计算机视觉

    为了帮助初识HarmonyOS的开发者快速入门,我们曾推出Hello HarmonyOS系列一共5期课程,从最基础的配置IDE和创建Hello World开始,详细介绍HarmonyOS基础.开发环境 ...

  10. 重新点亮linux 命令树————screen 命令和系统日志[二十四]

    前言 简单介绍一下screen 正文 因为我们终端关闭后,终端就消失了,故而希望有终端保持. 1.yum install screen 进行安装. 2.使用screen 进行进入 3.然后打开tail ...