.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(‘\0‘, 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(‘\0‘));
        }

        [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 Panel\Desktop", 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(@"root\CIMV2", 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;
                }
            }
        }
    }
}

完成.

原文地址:https://www.cnblogs.com/JimmySeraph/p/11696303.html

时间: 2024-08-29 07:05:30

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

微软 WCF的几种寄宿方式,寄宿IIS、寄宿winform、寄宿控制台、寄宿Windows服务

WCF寄宿方式是一种非常灵活的操作,可以在IIS服务.Windows服务.Winform程序.控制台程序中进行寄宿,从而实现WCF服务的运行,为调用者方便.高效提供服务调用.本文分别对这几种方式进行详细介绍并开发例子进行说明,以求大家对WCF寄宿的方式进行全面的认识和了解. 1. WCF服务的IIS服务寄宿 我在我前面几篇WCF开发框架的介绍文章中,介绍过了WCF常用的一种寄宿方式,IIS服务寄宿.这种寄宿方式是最为方便的方式,而且由于服务只需要IIS运行就能自动运行起来,因此广为使用. 创建这

.NET生成漂亮桌面背景

.NET生成漂亮桌面背景 一天,我朋友指着某某付费软件对我说,这个东西不错,每天生成一张桌面背景,还能学英语(放置名人名言和翻译)!我说,这东西搞不好我也能做,然后朋友说,"如果你搞出来了,我愿意给你付费$$$$元",然后就有了今天的故事??. 该桌面背景效果如下: 该桌面背景有4个特点: 背景为一张从必应下载的壁纸 英文为随机的名人名言,从API获取 注意文件下文有阴影,使用Direct2D 英文被翻译成了中文,使用了Azure Cognitive Service 当然还有重要的,需

第十三篇 一个安装、管理windows服务的桌面程序

在网上看到一个修改程序入口的程序去把windows 服务修改成控制台的程序,然后利用控制台的程序把服务安装和管理,也想起自己原来也写了一个对windows 报务管理的程序,不过是winform的. 界面如下(自己使用,界面比较丑陋): 首先需要添加一个帮助类: 代码如下: class Windows { /// <summary> /// 检查服务存在的存在性 /// </summary> /// <param name=" NameService "&g

如果写一个android桌面滑动切换屏幕的控件(二)

在viewgroup执行: public void snapToScreen(int whichScreen) { whichScreen = Math.max(0, Math.min(whichScreen, getChildCount() - 1)); boolean changingScreens = whichScreen != mCurrentScreen; mNextScreen = whichScreen; int mScrollX = this.getScrollX(); fin

如果写一个android桌面滑动切换屏幕的控件(三)

下面我们把这个控件内嵌到Layout中做一些动画和展示,效果图: 这个子控件可以上下移动,可以左右滑动,如果上下滑动距离大于左右滑动距离,则必须上下滑动 这样来写onTouch事件: @Override public boolean onTouchEvent(MotionEvent ev) { if (mVelocityTracker == null) { mVelocityTracker = VelocityTracker.obtain(); } mVelocityTracker.addMov

Windows7获取、更换桌面背景,C#

使用的API原型是 BOOL SystemParametersinfo(UINT uiAction,UINT uiParam,PVOID pvParam,UINT fWinlni); 在C#中定义如下: 1 /// <summary> 2 /// 查询或设置系统级参数 3 /// </summary> 4 /// <param name="uAction"></param> 5 /// <param name="uPara

CSS如何实现超链接背景切换

CSS如何实现超链接背景切换:建议:尽可能的手写代码,可以有效的提高学习效率和深度. 相当数量的网站在导航栏都有如此效果:当鼠标放在导航栏目上,背景图片会发生变化,移开之后又会还原原来的背景图片.下面简单介绍一下如何实现此效果.代码实例如下: <!DOCTYPE html> <html> <head> <meta charset=" utf-8"> <meta name="author" content=&quo

利用css3新增选择器制作背景切换

之前写css3的时间都是捡项目需要的来用,没有系统的学习过,这几天好好的补了一下css3的知识,真的获益匪浅!觉得新增的那些选择器是有用至极的!今天就来所这几天的所学做一个点击标签切换背景的效果,是纯css制作哦,不依赖js,算是作一个总结吧! 首先呢,前期工作当做是要先建好目录那些的了. index.html.css文件夹(包含style.css).img文件夹(包含1.jpg,2.jpg,3.jpg,4.jpg) 最后完成的效果如下(因为本人喜欢篮球,所以搞了几张nba人物卡通作素材),具体

JQ 操作样式,背景切换

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml" ><head> <title></title> <sty