【C#编程】设置屏保功能
本文最后更新于 361 天前,其中的信息可能已经有所发展或是发生改变。

背景:

上级领导来公司检查,要求电脑屏保设置指定图片幻灯片。

详细要求:

  1. 设定为图1.png~图7.png;
  2. 设定超时1分钟显示图片屏保幻灯片,每30秒换一张;
  3. 设置恢复时输入开机密码。

首先想到的是最简单的批处理,通过百度知道大师的回答得到bat:用批处理或者VBS脚本设置WIN/XP系统屏幕保护程序、等待时间和恢复时显示密码_百度知道 (baidu.com)

这个脚本只能放在一个文件夹中,诸君需要解压带有bat、屏保程序、图片的压缩包,再进行安装、执行bat,步骤繁琐。

主任要求,需要将诸君当成馬鹿,用以上的方式他们来讲太复杂,需要做到,一键,全部设定!

那就用C#挑战一下吧~

(由于公司都是由ghost装的win7,什么wget、curl都没有,批处理搞不来,.Net2.0还是有的):

  1. 首先将图片放到公司内外网络都可以访问的OA上,直接用OA中的下载链接直链下载图片,下载到C:/屏保图片;
  2. 将第三方幻灯片屏保程序也从OA上下载到%SystemRoot%\System32\ssMyPics.scr或%SystemRoot%\SysWOW64\ssMyPics.scr;
  3. 设定屏保程序、超时时间、恢复时输入开机密码的注册表(可以引用批处理文件);
  4. 立即生效(这一步网上没有答案,最后找到官方API文档)。

以下是代码,用的是C#控制台应用:

using System;
using System.IO;
using System.Net;
using System.Diagnostics;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace 一键设置屏保
{
    class Program
    {

        // user23动态库链接
        [DllImport("user32.dll", EntryPoint = "SystemParametersInfo")]
        // SystemParametersInfoA节点
        public static extern int SystemParametersInfo(int uAction, int uParam, string lpvParam, int fuWinIni);
        static void Main(string[] args)
        {
            //Console.WriteLine("按任意键开始");
            //Console.ReadKey(true);
            // filePath 文件路径名
            string filePath = System.Environment.SystemDirectory + "/ssMyPics.scr";
            // picPath 图片文件夹
            string picPath = "C:/屏保图片";
            //判断文件夹是否存在
            if (!Directory.Exists(picPath))
            {
                //创建文件夹
                try
                {
                    Console.WriteLine(picPath + "  屏保文件夹不存在!");
                    Directory.CreateDirectory(picPath);
                    Console.WriteLine(picPath + "  屏保文件夹创建成功!");
                }catch(Exception e){
                }
            }
            Console.WriteLine(picPath + "  屏保文件夹存在!");
            Console.WriteLine("正在下载第一张图...");
            WebClient client = new WebClient();
            client.Credentials = CredentialCache.DefaultCredentials;
            client.DownloadFile("第一张图链接", picPath + "/20230617-01.png");
            Console.WriteLine("第一张图下载完成");
            // ...
            Console.WriteLine("正在下载第七张图...");
            client.DownloadFile("第七张图链接", picPath + "/20230617-07.png");
            Console.WriteLine("第七张图下载完成");
            // 这里原来是用来判断32位或64位屏保文件安装位置的,但是发现用System.Environment.SystemDirectory 后不需要了
            /*if (IntPtr.Size == 8){
                // 64
                filePath = Environment.SpecialFolder.System + "\\SysWOW64\\ssMyPics.scr";
            } else {
                // 32
                filePath = Environment.SpecialFolder.System + "\\System32\\ssMyPics.scr";
            }*/
            if (!File.Exists(filePath))
            {
                Console.WriteLine(filePath + "  屏保程序不存在!");
                //FileStream fs = File.Create(filePath);// 创建文件位置测试
                //fs.Close();
                Console.WriteLine("正在下载屏幕保护程序...");
                client.DownloadFile("ssMyPics.scr屏保程序,下面会分享", filePath);
                Console.WriteLine("屏幕保护程序下载完成");
            }
            else
            {
                Console.WriteLine(filePath + "  屏保程序存在!");
                //执行读写操作
            }
            //批处理文件创建
            Console.WriteLine("创建批处理文件...");
            string cmdFileContent = "【这里批处理文件太长+折叠不美观,我会在下面列出】";
            // 批处理写入
            WriteBatFile(picPath + "/setting.bat", cmdFileContent);
            // 批处理执行
            RunBat(picPath + "/setting.bat");
            // 用SystemParametersInfoA节点操作
            // 设置屏保显示超时时间
            SystemParametersInfo(15, 60, "", 1);
            // 设置勾选屏保结束后显示登录界面或输入密码
            SystemParametersInfo(119, 1, "", 1);
            // 启动屏保测试
            // Process p = Process.Start(filePath);
            // p.WaitForExit();
            Console.WriteLine("设置完成!");
            Console.WriteLine("点击任何按键退出");
            MessageBox.Show("设置完成!");
            // Console.ReadKey(true);
            return;
        }

        //执行bat批处理
        public static void RunBat(string filePath)
        {
            ProcessStartInfo myBat = new ProcessStartInfo()
            {
                FileName = filePath,
                WorkingDirectory = Directory.GetCurrentDirectory(),
                UseShellExecute = false,
                //运行时隐藏dos窗口
                //CreateNoWindow = true,
                //设置该启动动作,会以管理员权限运行进程
                Verb = "runas",
            };
            Process.Start(myBat).WaitForExit();
        }

        //批处理文件创建
        public static void WriteBatFile(string filePath, string fileContent)
        {
            File.Delete(filePath);
            FileStream fs1 = new FileStream(filePath, FileMode.Create, FileAccess.Write);//创建写入文件
            StreamWriter sw = new StreamWriter(fs1, System.Text.Encoding.GetEncoding("GB2312"));
            sw.WriteLine(fileContent);//开始写入值
            sw.Close();
            fs1.Close();
        }
    }
}

批处理文件源码(By 依梦琴瑶 已修改部分):

@echo off & title 一键设置指定图片目录为屏幕保护
::设置包含图片文件夹的主目录路径,留空为当前脚本所在目录
set ImageDir=
::设置显示屏保时的等待时间(分钟),有效值(1-9999)
set TimeOut=1
::设置是否启用登录屏幕,1 启用,0 禁用
set Login=1
::是否立即生效,1 立即(系统将会注销当前帐户),其它数字下次开机后生效
set Effective=1
::设置图片更换频率(毫秒),有效值(6000 - 180000)
set Interval=6000
::设置图片在屏幕上显示的尺寸大小(%),有效值(25 - 100)
set Percent=100
::设置是否拉伸图片,1 允许,0 拒绝
set Stretch=0
::设置是否显示图片名,1 显示,0 隐藏
set ShowName=0
::设置是否禁用过渡效果,1 禁用,0 启用
set Transition=1
::设置是否使用键盘滚动浏览,1 启用,0 禁用
set Control=1
::1 跳转,0 忽略
set Pay=1
::主执行代码,如非必要,请勿修改,以免执行出错。
set "ScrFile=C:\Windows\System32\ssMyPics.scr"
if not exist "%ScrFile%" (
    color 0C & title 缺失图片收藏幻灯片(ssMyPics.scr)屏幕保护程序 By 依梦琴瑶
    echo 如果您使用的是Vista,及其以上的系统,由于系统自带的
    echo “照片”(PhotoScreensaver.scr^)屏幕保护程序,不能使用
    echo 命令方式进行设置,所以我将会使用XP系统上的图片屏幕保
    echo 护程序来实现设置,但由于您系统中缺失了ssMyPics.scr,
	echo 请先双击文件夹中的ssMyPics_Install.exe进行安装,
	echo 安装后再运行脚本。
    :: pause
	exit
)
cd /d "%~dp0" & color 0a
if not defined ImageDir set "ImageDir=%cd%"
if not exist "%ImageDir%" (
    color 0C & title 路径不存在
    echo 设置的图片主目录路径不存在
    ping 127.0.0.1 -n "4">nul
    exit
)
set /a TimeOut*=60
set "Key=HKCU\Control Panel"
set "SSS=Screen Saver.Slideshow"
reg add "%key%\Desktop" /v SCRNSAVE.EXE /t REG_SZ /d "%ScrFile%" /f
reg add "%key%\Desktop" /v ScreenSaveTimeOut /t REG_SZ /d "%TimeOut%" /f
reg add "%key%\Desktop" /v ScreenSaverIsSecure /t REG_SZ /d "%Login%" /f
reg add "%key%\%SSS%" /v ChangeInterval /t REG_DWORD /d %Interval% /f
reg add "%key%\%SSS%" /v MaxScreenPercent /t REG_DWORD /d %Percent% /f
reg add "%key%\%SSS%" /v AllowStretching /t REG_DWORD /d %Stretch% /f
reg add "%key%\%SSS%" /v DisplayFilename /t REG_DWORD /d %ShowName% /f
reg add "%key%\%SSS%" /v DisableTransitions /t REG_DWORD /d %Transition% /f
reg add "%key%\%SSS%" /v AllowKeyboardControl /t REG_DWORD /d %Control% /f
reg add "%key%\%SSS%" /v ImageDirectory /t REG_SZ /d "%ImageDir%" /f
echo 完成!

突破:

由于更新注册表后,必须要注销,主任说注销很麻烦,有时候没保存文件、开机很慢,用户又要发牢骚。行。

网上给出的答案什么重启explorer(无效)、更新组策略(根本没有对组策略进行变更)、F5刷新桌面(关刷新桌面什么事)……都没用,直到,找到一篇:systemparametersinfo详细(更改屏保设置)_蝈蝈(GuoGuo)的博客-CSDN博客,让我有了灵感,找到了官方接口文档:SystemParametersInfoA 函数 (winuser.h) – Win32 apps | Microsoft Learn

文档中对博客中的修改屏保等待时间的功能接口进行了解释:

16进制的0x00F就是10进制的15,由此可以知道如何调用这个方法。随后找到修改0x77,10进制119,即SystemParametersInfo(119, 1, "", 1);即可,1是True,0是False。

在文章:c# 更换桌面壁纸 – 徐驰 – 博客园 (cnblogs.com)中了解C#调用方法。

最后测试可行!

以下是屏保安装程序和屏保scr下载链接:

分享名称:屏保程序 分享链接:https://kb.itpno.com/#s/9X4uYyUg 访问密码:iTPno.

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
Source: https://github.com/MengXi2021/Argon-Emoji-DailyNotes
Source: https://github.com/Ghost-chu/argon-huhu-emotions
Source: github.com/zhheo/Sticker-Heo
颜文字
Emoji
小恐龙
花!
每日手帐
呼呼
Heo
上一篇
下一篇