.NET(C#)实现桌面背景切换(控制台应用程序,windows服务版的未实现成功)

AdvancedBackgroundJimmy.Program.cs

using AdvancedBackground;
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.ServiceProcess;
using System.Threading.Tasks;
using System.Timers;

namespace AdvancedBackgroundJimmy
{
    [System.Runtime.Remoting.Contexts.Synchronization]
    static class Program
    {

        const int SPI_GETDESKWALLPAPER = 0x73;
        const int MAX_PATH = 260;
        const int SPI_SETDESKWALLPAPER = 0x14;
        const int SPIF_UPDATEINIFILE = 0x01;
        const int SPIF_SENDININICHANGE = 0x02;
        static string photoFileDirPath = @"g:/Photos/Camera/";
        static DirectoryInfo photoDir = new DirectoryInfo(photoFileDirPath);
        static FileInfo[] photoFileArr = photoDir.GetFiles();
        static int PHOTO_PER_WAIT = 3000;
        static string log_path = @"g:/TestLog/AdvancedBackgroundJimmy/log.txt";
        static FileInfo logFileInfo = new FileInfo(log_path);
        static string log = null;

        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]  
        static void Main()
        {
            //ServiceBase[] servicesToRun = new ServiceBase[]
            //{ 
            //    new AdvancedBackgroundServiceJimmy()
            //};
            //ServiceBase.Run(servicesToRun);
            AutoPhoto();
        }

        public static void AutoPhoto()
        {
            try
            {
                log = "进入AutoPhoto方法!" + System.Environment.NewLine;
                File.AppendAllText(log_path, log);
                FileInfo[] fileArr = photoFileArr;
                for (int i = 0; i < fileArr.Length; i++)
                {
                    FileInfo photoFile = fileArr[i];
                    log = "当前图片路径:" + photoFile.FullName + System.Environment.NewLine;
                    File.AppendAllText(log_path, log);
                    SetWallpaper2(photoFile.FullName, WallpaperStyle.Centered);
                    //SHChangeNotify(HChangeNotifyEventID.SHCNE_ASSOCCHANGED, HChangeNotifyFlags.SHCNF_IDLIST, IntPtr.Zero, IntPtr.Zero);
                    if (i == fileArr.Length - 1)
                    {
                        i = -1;
                    }
                    System.Threading.Thread.Sleep(PHOTO_PER_WAIT);
                }
            }
            catch(Exception e)
            {
                log = e.Message + System.Environment.NewLine;
                File.AppendAllText(log_path, log);
            }
        }

        const int WM_SETTINGCHANGE = 0x001A;
        const int HWND_BROADCAST = 0xffff;

        static IntPtr result1;

        public enum SendMessageTimeoutFlags : uint
        {
            SMTO_NORMAL = 0x0000,
            SMTO_BLOCK = 0x0001,
            SMTO_ABORTIFHUNG = 0x0002,
            SMTO_NOTIMEOUTIFNOTHUNG = 0x0008
        }

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

        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
        static extern int GetLastError();

        public enum WallpaperStyle : int
        {
            Tiled,
            Centered,
            Stretched,
            Fill,
            Fit
        }

        /// <summary>
        /// 返回当前的系统壁纸路径
        /// </summary>
        /// <returns></returns>
        public static string GetDesktopWallpaper()
        {
            string wallpaper = new string('', MAX_PATH);
            try
            {
                int ret = SystemParametersInfo(SPI_GETDESKWALLPAPER, (int)wallpaper.Length, wallpaper, 0);
            }
            catch (Exception e)
            {
                log = e.Message + System.Environment.NewLine;
                File.AppendAllText(log_path, log);
            }
            return wallpaper.Substring(0, wallpaper.IndexOf(''));
        }

        [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        public static extern IntPtr SendMessageTimeout(
        IntPtr windowHandle,
        uint Msg,
        IntPtr wParam,
        IntPtr lParam,
        SendMessageTimeoutFlags flags,
        uint timeout,
        out IntPtr result
        );

         /// 桌面刷新
        /// </summary>
        [DllImport("shell32.dll")]
        public static extern void SHChangeNotify(HChangeNotifyEventID wEventId, HChangeNotifyFlags uFlags, IntPtr dwItem1, IntPtr dwItem2);

        public static void DeskRef()
        {
            SHChangeNotify(HChangeNotifyEventID.SHCNE_ASSOCCHANGED, HChangeNotifyFlags.SHCNF_IDLIST, IntPtr.Zero, IntPtr.Zero);
        }

        #region 
        [Flags]
        public enum HChangeNotifyFlags
        {
            SHCNF_DWORD = 0x0003,
            SHCNF_IDLIST = 0x0000,
            SHCNF_PATHA = 0x0001,
            SHCNF_PATHW = 0x0005,
            SHCNF_PRINTERA = 0x0002,
            SHCNF_PRINTERW = 0x0006,
            SHCNF_FLUSH = 0x1000,
            SHCNF_FLUSHNOWAIT = 0x2000
        }
        #endregion

        #region enum HChangeNotifyEventID
        [Flags]
        public enum HChangeNotifyEventID
        {
            SHCNE_ALLEVENTS = 0x7FFFFFFF,
            SHCNE_ASSOCCHANGED = 0x08000000,
            SHCNE_ATTRIBUTES = 0x00000800,
            SHCNE_CREATE = 0x00000002,
            SHCNE_DELETE = 0x00000004,
            SHCNE_DRIVEADD = 0x00000100,
            SHCNE_DRIVEADDGUI = 0x00010000,
            SHCNE_DRIVEREMOVED = 0x00000080,
            SHCNE_EXTENDED_EVENT = 0x04000000,
            SHCNE_FREESPACE = 0x00040000,
            SHCNE_MEDIAINSERTED = 0x00000020,
            SHCNE_MEDIAREMOVED = 0x00000040,
            SHCNE_MKDIR = 0x00000008,
            SHCNE_NETSHARE = 0x00000200,
            SHCNE_NETUNSHARE = 0x00000400,
            SHCNE_RENAMEFOLDER = 0x00020000,
            SHCNE_RENAMEITEM = 0x00000001,
            SHCNE_RMDIR = 0x00000010,
            SHCNE_SERVERDISCONNECT = 0x00004000,
            SHCNE_UPDATEDIR = 0x00001000,
            SHCNE_UPDATEIMAGE = 0x00008000,
        }
        #endregion

        [DllImport("user32.dll")]
        public static extern bool InvalidateRect(IntPtr hwnd, IntPtr lpRect, bool bErase);

        public static void SetWallpaper2(string path, WallpaperStyle style)
        {
            try
            {
                log = "进入SetWallpaper方法!" + System.Environment.NewLine;
                File.AppendAllText(log_path, log);
                log = "时间:" + DateTime.Now.ToString() + System.Environment.NewLine;
                File.AppendAllText(log_path, log);
                //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 PanelDesktop", true);
                key.SetValue(@"Wallpaper", path);
                if (style == WallpaperStyle.Stretched)
                {
                    key.SetValue(@"WallpaperStyle", 2.ToString());
                    key.SetValue(@"TileWallpaper", 0.ToString());
                }
                else if (style == WallpaperStyle.Centered)
                {
                    key.SetValue(@"WallpaperStyle", 1.ToString());
                    key.SetValue(@"TileWallpaper", 0.ToString());
                }
                else if (style == WallpaperStyle.Tiled)
                {
                    key.SetValue(@"WallpaperStyle", 1.ToString());
                    key.SetValue(@"TileWallpaper", 1.ToString());
                }
                else if (style == WallpaperStyle.Fit) //Win 7 or later
                {
                    key.SetValue(@"WallpaperStyle", 6.ToString());
                    key.SetValue(@"TileWallpaper", 0.ToString());
                }
                else if (style == WallpaperStyle.Fill)    //Win 7 or later
                {
                    key.SetValue(@"WallpaperStyle", 10.ToString());
                    key.SetValue(@"TileWallpaper", 1.ToString());
                }
                else
                {

                }
                int ret = SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, path, SPIF_UPDATEINIFILE | SPIF_SENDININICHANGE);
                if (ret > 0)
                {
                    log = "结果:" + ret + System.Environment.NewLine;
                    File.AppendAllText(log_path, log);
                }
                else
                {
                    int errCode = GetLastError();
                    log = "错误码:" + errCode + System.Environment.NewLine;
                    File.AppendAllText(log_path, log);
                }
                key.Flush();
                key.Close();
                //通知所有打开的程序注册表以修改
                //SendMessageTimeout(new IntPtr(HWND_BROADCAST), WM_SETTINGCHANGE, IntPtr.Zero, IntPtr.Zero, SendMessageTimeoutFlags.SMTO_NORMAL, 1000, out result1);
                //DeskRef();
                //InvalidateRect(IntPtr.Zero, IntPtr.Zero, true);
            }
            catch (Exception e)
            {
                log = e.Message + System.Environment.NewLine;
                File.AppendAllText(log_path, log);
            }
        }

    }
}

ProjectInstaller.cs

using Microsoft.Win32;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration.Install;
using System.Linq;
using System.Management;

namespace AdvancedBackgroundJimmy
{
    [RunInstaller(true)]
    public partial class ProjectInstaller : System.Configuration.Install.Installer
    {

        public ProjectInstaller()
        {
            InitializeComponent();
        }

        protected override void OnCommitted(System.Collections.IDictionary savedState)
        {
            base.OnCommitted(savedState);
            //将服务更改为允许桌面交互模式
            ConnectionOptions coOptions = new ConnectionOptions();
            coOptions.Impersonation = ImpersonationLevel.Impersonate;
            ManagementScope mgmtScope = new System.Management.ManagementScope(@"rootCIMV2", coOptions);
            mgmtScope.Connect();
            ManagementObject wmiService;
            wmiService = new ManagementObject("Win32_Service.Name='" + this.serviceInstaller1.ServiceName + "'");
            ManagementBaseObject InParam = wmiService.GetMethodParameters("Change");
            InParam["DesktopInteract"] = true;
            ManagementBaseObject OutParam = wmiService.InvokeMethod("Change", InParam, null);
        }

    }
}

AdvancedBackgroundServiceJimmy.cs

using AdvancedBackground;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.ServiceProcess;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace AdvancedBackgroundJimmy
{
    partial class AdvancedBackgroundServiceJimmy : ServiceBase
    {

        static String log_path = @"g:/TestLog/AdvancedBackgroundJimmy/log.txt";
        static FileInfo logFileInfo = new FileInfo(log_path);
        static String log = null;
        static Thread thread = null;

        [DllImport("user32.dll")]
        static extern int GetDesktopWindow();

        [DllImport("user32.dll")]
        static extern IntPtr GetProcessWindowStation();

        [DllImport("kernel32.dll")]
        static extern IntPtr GetCurrentThreadId();

        [DllImport("user32.dll")]
        static extern IntPtr GetThreadDesktop(IntPtr dwThread);

        [DllImport("user32.dll")]
        static extern IntPtr OpenWindowStation(string a, bool b, int c);

        [DllImport("user32.dll")]
        static extern IntPtr OpenDesktop(string lpszDesktop, uint dwFlags,
        bool fInherit, uint dwDesiredAccess);

        [DllImport("user32.dll")]
        static extern IntPtr CloseDesktop(IntPtr p);

        [DllImport("rpcrt4.dll", SetLastError = true)]
        static extern IntPtr RpcImpersonateClient(int i);

        [DllImport("rpcrt4.dll", SetLastError = true)]
        static extern IntPtr RpcRevertToSelf();

        [DllImport("user32.dll")]
        static extern IntPtr SetThreadDesktop(IntPtr a);

        [DllImport("user32.dll")]
        static extern IntPtr SetProcessWindowStation(IntPtr a);

        [DllImport("user32.dll")]
        static extern IntPtr CloseWindowStation(IntPtr a);

        public AdvancedBackgroundServiceJimmy()
        {
            InitializeComponent();
            if (!logFileInfo.Exists)
            {
                logFileInfo.CreateText();
            }
        }

        protected override void OnStart(string[] args)
        {
            if (!logFileInfo.Exists)
            {
                logFileInfo.CreateText();
            }
            log = "进入OnStart方法!" + System.Environment.NewLine;
            File.AppendAllText(log_path, log);
            ThreadStart threadStart = new ThreadStart(delegate()
            {
                try
                {
                    if (!logFileInfo.Exists)
                    {
                        logFileInfo.CreateText();
                    }
                    GetDesktopWindow();
                    IntPtr hwinstaSave = GetProcessWindowStation();
                    IntPtr dwThreadId = GetCurrentThreadId();
                    IntPtr hdeskSave = GetThreadDesktop(dwThreadId);
                    IntPtr hwinstaUser = OpenWindowStation("WinSta0", false, 33554432);
                    if (hwinstaUser == IntPtr.Zero)
                    {
                        RpcRevertToSelf();
                        return;
                    }
                    SetProcessWindowStation(hwinstaUser);
                    IntPtr hdeskUser = OpenDesktop("Default", 0, false, 33554432);
                    RpcRevertToSelf();
                    if (hdeskUser == IntPtr.Zero)
                    {
                        SetProcessWindowStation(hwinstaSave);
                        CloseWindowStation(hwinstaUser);
                        return;
                    }
                    SetThreadDesktop(hdeskUser);
                    IntPtr dwGuiThreadId = dwThreadId;
                    AdvancedBackgroundJimmy.Program.AutoPhoto();
                    dwGuiThreadId = IntPtr.Zero;
                    SetThreadDesktop(hdeskSave);
                    SetProcessWindowStation(hwinstaSave);
                    CloseDesktop(hdeskUser);
                    CloseWindowStation(hwinstaUser);
                }
                catch (Exception e)
                {
                    log = e.Message + System.Environment.NewLine;
                    File.AppendAllText(log_path, log);
                }
            });
            thread = new Thread(threadStart);
            thread.IsBackground = true;
            thread.Start();
            //AdvancedBackgroundJimmy.Program.AutoPhoto();
        }

        protected override void OnStop()
        {
            if(thread != null)  
            {
                if (thread.IsAlive)
                {
                    thread.Abort();
                    thread = null;
                }
            }  
        }
    }
}

完成.

修改by:ラピスラズリ(Dawn)

修改日期:2019-10-18 9:22:46

问题:去掉了不小心加上的无用代码

2015年10月-2016年3月 总计:5个月.
2016年11月-2017年6月 总计:7个月.
2017年7月-2018年4月 总计:9个月.
2018年5月-2018年5月 总计:1个月.
2018年6月-2018年12月 总计:6个月.
2019年1月-2019年12月 总计11个月.
2020年2月-2021年2月 总计13个月.
所有总计:5+7+9+1+6+11+13=52个月(4年4个月).
本人认同二元论.我是理想主义者,现实主义者,乐观主义者,有一定的完美主义倾向.不过,一直都是咸鱼(菜鸟),就算有机会,我也不想咸鱼翻身.(并不矛盾,因为具体情况具体分析)
英语,高等数学,考研,其他知识学习打卡交流QQ群:946556683
原文地址:https://www.cnblogs.com/JimmySeraph/p/11696303.html