调查发现网上所有类似教程都是针对Windows聚焦的,本文独家提供对于非Windows聚焦的桌面/锁屏壁纸获取方法!
桌面
桌面壁纸位于:%APPDATA%\Microsoft\Windows\Themes
其中%APPDATA%是用户特定的环境变量指定的路径,通常是C:\Users\用户名\AppData\Roaming。可以在PowerShell中输入`gci env:APPDATA`查询当前用户的%APPDATA%路径。
如果你只有一个显示器
此目录下将会有一个名为CachedFiles的目录
目录下只有一张图,就是你当前的桌面壁纸
如果你有多个显示器
多显示屏时情况变得复杂,并不是简单地多一张图,而是取决于【选择适合你的桌面图象】这项设置的选项。
则是,选择【填充】、【适应】、【拉伸】时,每个显示屏会显示不同的图像,在Themes目录下会有多个无扩展名的文件Transcoded_xxx,其中xxx是显示器从000开始的顺序编号。例如有两个显示器时:
虽然没有扩展名,但这两个文件本质上仍然是JPG图像,只要加上.jpg扩展名就能打开。
选择【平铺】、【居中】、【跨区】时,所有显示屏共享同一张壁纸,在Themes目录下会有一个无扩展名的TranscodedWallpaper文件:
同样本质上是个JPG图像,加上扩展名就能打开。
编程接口
此COM接口支持桌面壁纸的获取和设置,还支持幻灯片放映图集和顺序,包括壁纸展开方式……堪称万能,完美覆盖了你可能需要对桌面壁纸进行的任何操作,功能足够丰富。实际上,你只需要使用这个API就可以直接单独取得和设置任何一个显示器上的桌面壁纸图像,不需要知道上文所述的文件系统内的存储方式。唯一的缺点就是COM接口使用起来比较繁琐,你可能需要专门学习COM接口使用方法。
UserProfilePersonalizationSettings.TrySetWallpaperImageAsync 方法https://learn.microsoft.com/zh-cn/uwp/api/windows.system.userprofile.userprofilepersonalizationsettings.trysetwallpaperimageasync此Windows运行时API只支持设置桌面壁纸,而且不能区分不同显示器,只能给所有显示器设置同一张桌面壁纸。如果你只有设置的需求,用这个API比较简单,相比于繁琐的COM,在.NET和C++中都很容易使用。
锁屏
锁屏壁纸位于:%ProgramData%\Microsoft\Windows\SystemData\用户SID\ReadOnly
其中%ProgramData%是计算机特定的环境变量,可在PowerShell中用`gci env:ProgramData`查找本机的%ProgramData%变量值,一般来说是【C:\ProgramData】
【用户SID】是用户在当前Windows计算机上的唯一标识符,可以在PowerShell中输入`whoami /user`查询自己的用户SID
不同于桌面,锁屏壁纸的管理更加复杂。首先,此目录通常是不向一般用户开放访问权限的,可能需要设置访问控制列表(安全权限)。其次,此目录下并不直接存放壁纸图片,而是会有1~6个子目录,分别为LockScreen_A~F,每个子目录下都是同一张图的不同缩放和裁剪尺寸。
上图是我的计算机上,只有3个,你的计算机上最多可能会有6个。这些子目录中只有一个是真正存放了当前的锁屏壁纸图,其它都是缓存的历史记录。为了查询哪一个是真正的当前锁屏,我们还需要翻阅注册表:计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\SystemProtectedUserData\用户SID\AnyoneRead\LockScreen
最后的LockScreen键不一定存在——如果用户没有设置过任何锁屏,这个键就可能是不存在的。
我们需要关注的是此键的(默认)值,它是一个6个大写英文字母组成的字符串,其首字母就对应着当前壁纸的编号。如上图首字母是A,说明LockScreen_A就是目前正在使用的锁屏壁纸。相信你也能猜到,后面的CB就是以前曾经使用过的锁屏壁纸历史记录,ZYX则是未使用的占位符。实际上,完全可以通过修改这个键值来切换当前锁屏图,例如你把开头的ACB改成BAC,就能看到LockScreen_B中的图片变成了当前锁屏图。
我们打开LockScreen_A:
其中存放了同一张图的多种不同的裁剪和缩放尺寸,这些都是在设置一张新的锁屏图时自动生成的。其中LockScreen.jpg是原图,其它都是经过修改的。
编程接口
UserProfilePersonalizationSettings.TrySetLockScreenImageAsync 方法https://learn.microsoft.com/zh-cn/uwp/api/windows.system.userprofile.userprofilepersonalizationsettings.trysetlockscreenimageasync 此Windows运行时API只能用于设置当前锁屏壁纸,不能获取。
LockScreen 类https://learn.microsoft.com/zh-cn/uwp/api/windows.system.userprofile.lockscreen此Windows运行时API支持获取和设置当前锁屏壁纸。但是,获取锁屏壁纸可能会失败,原因未知。一旦此方法失败,你将只能通过上文所述的方法,手动检索文件系统和注册表来获取当前锁屏壁纸。
不同于桌面壁纸,Windows没有提供可靠的COM接口或其它API支持获取当前锁屏壁纸。当然也可能还有我不知道的欢迎指出。第三方库也大多是针对Windows聚焦,获取原生锁屏壁纸的可靠解决方案,我没有在网上搜索到任何其它。