找回密码
 注册
搜索
[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
查看: 95|回复: 0

[系统相关] [分享]批处理删除桌面壁纸源图片并更换为下一张

[复制链接]
发表于 昨天 05:46 | 显示全部楼层 |阅读模式
在壁纸设置为幻灯片后,如果遇到不喜欢的壁纸,点击原本的下一个桌面背景菜单,会切换到下一张,然而这样治标不治本,以后还是会出现,使用此脚本可直接删除壁纸源文件并切换到下一张。
  1. <#*,:
  2. @echo off
  3. chcp 65001 >nul

  4. rem "脚本为批处理脚本,扩展名为.bat ,编码为UTF-8。(主要代码来自AI)

  5. rem "用法一:直接双击脚本;
  6. rem "用法二:添加为桌面右键菜单,实现便捷操作。( 1.下载第三方工具nircmd ,放在systems32目录下;2.将本脚本文件永久放在某固定目录下,然后右键以管理员执行1次即可添加右键菜单; )
  7. rem "注意:删除壁纸操作不可逆,注意备份;用法二默认删除 Windows自带的下一个桌面背景菜单。



  8. set ContextMenuText=下一个桌面背景#


  9. cd /d "%~dp0"
  10. set "batchfile=%~f0"
  11. set psline=Powershell.exe -ExecutionPolicy Bypass -C "Set-Location -LiteralPath ([Environment]::CurrentDirectory);. ([ScriptBlock]::Create([IO.File]::ReadAllText($env:batchfile,[Text.Encoding]::GetEncoding(0) )) )"

  12. if "%~1" equ "r" (
  13.         %psline%
  14. ) else (
  15.         fltmc >nul 2>&1
  16.         if not errorlevel 1 (
  17.                 reg delete "HKCU\Software\Classes\DesktopBackground\shellex\ContextMenuHandlers\DesktopSlideshow" /f >nul 2>&1
  18.                 reg delete "HKCR\DesktopBackground\shellex\ContextMenuHandlers\DesktopSlideshow" /f >nul 2>&1
  19.                 reg delete "HKCU\Software\Classes\DesktopBackground\Shell" /ve /f >nul 2>&1
  20.                 reg add "HKCU\Software\Classes\DesktopBackground\Shell\M_DeleteAndReplaceWallpaper" /v "MUIVerb" /t REG_SZ /d "%ContextMenuText%" /f
  21.                 reg add "HKCU\Software\Classes\DesktopBackground\Shell\M_DeleteAndReplaceWallpaper" /v "Position" /t REG_SZ /d "Bottom" /f
  22.                 reg add "HKCU\Software\Classes\DesktopBackground\Shell\M_DeleteAndReplaceWallpaper" /v "Icon" /t REG_SZ /d "imageres.dll,-5347" /f
  23.                 reg add "HKCU\Software\Classes\DesktopBackground\Shell\M_DeleteAndReplaceWallpaper\command" /ve /t REG_SZ /d "nircmd.exe elevatecmd exec hide \"C:\Windows\System32\cmd.exe\" /d /c call \"%~f0\" r" /f
  24.         ) else (
  25.                 %psline%
  26.         )
  27. )
  28. exit /b
  29. #>



  30. try {
  31.     Add-Type -TypeDefinition @'
  32. using System;
  33. using System.Collections.Generic;
  34. using System.IO;
  35. using System.Runtime.InteropServices;
  36. using System.Threading;

  37. public static class WallpaperAction
  38. {
  39.     [StructLayout(LayoutKind.Sequential)]
  40.     private struct RECT
  41.     {
  42.         public int Left;
  43.         public int Top;
  44.         public int Right;
  45.         public int Bottom;
  46.     }

  47.     [ComImport]
  48.     [Guid("B92B56A9-8B55-4E14-9A89-0199BBB6F93B")]
  49.     [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
  50.     private interface IDesktopWallpaper
  51.     {
  52.         [PreserveSig]
  53.         int SetWallpaper(
  54.             [MarshalAs(UnmanagedType.LPWStr)] string monitorID,
  55.             [MarshalAs(UnmanagedType.LPWStr)] string wallpaper);

  56.         [PreserveSig]
  57.         int GetWallpaper(
  58.             [MarshalAs(UnmanagedType.LPWStr)] string monitorID,
  59.             out IntPtr wallpaper);

  60.         [PreserveSig]
  61.         int GetMonitorDevicePathAt(
  62.             uint monitorIndex,
  63.             out IntPtr monitorID);

  64.         [PreserveSig]
  65.         int GetMonitorDevicePathCount(
  66.             out uint count);

  67.         [PreserveSig]
  68.         int GetMonitorRECT(
  69.             [MarshalAs(UnmanagedType.LPWStr)] string monitorID,
  70.             out RECT displayRect);

  71.         [PreserveSig]
  72.         int SetBackgroundColor(uint color);

  73.         [PreserveSig]
  74.         int GetBackgroundColor(out uint color);

  75.         [PreserveSig]
  76.         int SetPosition(uint position);

  77.         [PreserveSig]
  78.         int GetPosition(out uint position);

  79.         [PreserveSig]
  80.         int SetSlideshow(IntPtr items);

  81.         [PreserveSig]
  82.         int GetSlideshow(out IntPtr items);

  83.         [PreserveSig]
  84.         int SetSlideshowOptions(
  85.             uint options,
  86.             uint slideshowTick);

  87.         [PreserveSig]
  88.         int GetSlideshowOptions(
  89.             out uint options,
  90.             out uint slideshowTick);

  91.         [PreserveSig]
  92.         int AdvanceSlideshow(
  93.             [MarshalAs(UnmanagedType.LPWStr)] string monitorID,
  94.             uint direction);

  95.         [PreserveSig]
  96.         int GetStatus(out uint state);

  97.         [PreserveSig]
  98.         int Enable(
  99.             [MarshalAs(UnmanagedType.Bool)] bool enable);
  100.     }

  101.     private sealed class MonitorInfo
  102.     {
  103.         public string Id;
  104.         public string Path;
  105.     }

  106.     private static readonly Guid DesktopWallpaperClsid =
  107.         new Guid("C2CF3110-460E-4FC1-B9D0-8A1C0C9CC4BD");

  108.     private static void ThrowIfFailed(int result)
  109.     {
  110.         if (result < 0)
  111.         {
  112.             Marshal.ThrowExceptionForHR(result);
  113.         }
  114.     }

  115.     private static string ReadAndFreeString(IntPtr pointer)
  116.     {
  117.         if (pointer == IntPtr.Zero)
  118.         {
  119.             return String.Empty;
  120.         }

  121.         try
  122.         {
  123.             string value = Marshal.PtrToStringUni(pointer);
  124.             return value ?? String.Empty;
  125.         }
  126.         finally
  127.         {
  128.             Marshal.FreeCoTaskMem(pointer);
  129.         }
  130.     }

  131.     private static string GetMonitorId(
  132.         IDesktopWallpaper desktop,
  133.         uint index)
  134.     {
  135.         IntPtr pointer = IntPtr.Zero;

  136.         ThrowIfFailed(
  137.             desktop.GetMonitorDevicePathAt(index, out pointer)
  138.         );

  139.         return ReadAndFreeString(pointer);
  140.     }

  141.     private static string GetWallpaperPath(
  142.         IDesktopWallpaper desktop,
  143.         string monitorId)
  144.     {
  145.         IntPtr pointer = IntPtr.Zero;

  146.         ThrowIfFailed(
  147.             desktop.GetWallpaper(monitorId, out pointer)
  148.         );

  149.         return ReadAndFreeString(pointer);
  150.     }

  151.     public static int Run()
  152.     {
  153.         object comObject = null;

  154.         try
  155.         {
  156.             Type comType =
  157.                 Type.GetTypeFromCLSID(
  158.                     DesktopWallpaperClsid,
  159.                     true
  160.                 );

  161.             comObject = Activator.CreateInstance(comType);

  162.             IDesktopWallpaper desktop =
  163.                 (IDesktopWallpaper)comObject;

  164.             uint monitorCount = 0;

  165.             ThrowIfFailed(
  166.                 desktop.GetMonitorDevicePathCount(
  167.                     out monitorCount
  168.                 )
  169.             );

  170.             if (monitorCount == 0)
  171.             {
  172.                 throw new InvalidOperationException(
  173.                     "No monitor was found."
  174.                 );
  175.             }

  176.             List<MonitorInfo> monitors =
  177.                 new List<MonitorInfo>();

  178.             HashSet<string> oldPaths =
  179.                 new HashSet<string>(
  180.                     StringComparer.OrdinalIgnoreCase
  181.                 );

  182.             for (uint i = 0; i < monitorCount; i++)
  183.             {
  184.                 string monitorId =
  185.                     GetMonitorId(desktop, i);

  186.                 string wallpaperPath =
  187.                     GetWallpaperPath(
  188.                         desktop,
  189.                         monitorId
  190.                     );

  191.                 if (String.IsNullOrWhiteSpace(
  192.                         wallpaperPath))
  193.                 {
  194.                     continue;
  195.                 }

  196.                 if (!File.Exists(wallpaperPath))
  197.                 {
  198.                     continue;
  199.                 }

  200.                 MonitorInfo info =
  201.                     new MonitorInfo();

  202.                 info.Id = monitorId;
  203.                 info.Path = wallpaperPath;

  204.                 monitors.Add(info);
  205.                 oldPaths.Add(wallpaperPath);
  206.             }

  207.             if (monitors.Count == 0)
  208.             {
  209.                 throw new InvalidOperationException(
  210.                     "The current wallpaper source file was not found."
  211.                 );
  212.             }

  213. int advanceResult =
  214.     desktop.AdvanceSlideshow(
  215.         null,
  216.         0
  217.     );

  218. if (advanceResult < 0)
  219. {
  220.     throw new COMException(
  221.         "AdvanceSlideshow failed. HRESULT: 0x" +
  222.         advanceResult.ToString("X8"),
  223.         advanceResult
  224.     );
  225. }

  226.             HashSet<string> displayedPaths =
  227.                 new HashSet<string>(
  228.                     StringComparer.OrdinalIgnoreCase
  229.                 );

  230.             DateTime deadline =
  231.                 DateTime.UtcNow.AddSeconds(10);

  232.             while (DateTime.UtcNow < deadline)
  233.             {
  234.                 displayedPaths.Clear();

  235.                 foreach (MonitorInfo monitor in monitors)
  236.                 {
  237.                     string currentPath =
  238.                         GetWallpaperPath(
  239.                             desktop,
  240.                             monitor.Id
  241.                         );

  242.                     if (!String.IsNullOrWhiteSpace(
  243.                             currentPath))
  244.                     {
  245.                         displayedPaths.Add(currentPath);
  246.                     }
  247.                 }

  248.                 bool oldImageStillDisplayed = false;

  249.                 foreach (string oldPath in oldPaths)
  250.                 {
  251.                     if (displayedPaths.Contains(oldPath))
  252.                     {
  253.                         oldImageStillDisplayed = true;
  254.                         break;
  255.                     }
  256.                 }

  257.                 if (!oldImageStillDisplayed)
  258.                 {
  259.                     break;
  260.                 }

  261.                 Thread.Sleep(200);
  262.             }

  263.             int deletedCount = 0;

  264.             foreach (string oldPath in oldPaths)
  265.             {
  266.                 if (displayedPaths.Contains(oldPath))
  267.                 {
  268.                     continue;
  269.                 }

  270.                 if (File.Exists(oldPath))
  271.                 {
  272.                     File.Delete(oldPath);
  273.                     deletedCount++;
  274.                 }
  275.             }

  276.             if (deletedCount == 0)
  277.             {
  278.                 throw new InvalidOperationException(
  279.                     "The wallpaper did not change, so no file was deleted."
  280.                 );
  281.             }

  282.             return deletedCount;
  283.         }
  284.         finally
  285.         {
  286.             if (comObject != null &&
  287.                 Marshal.IsComObject(comObject))
  288.             {
  289.                 Marshal.FinalReleaseComObject(
  290.                     comObject
  291.                 );
  292.             }
  293.         }
  294.     }
  295. }
  296. '@ -ErrorAction Stop

  297.     [WallpaperAction]::Run() | Out-Null
  298.     exit 0
  299. }
  300. catch {
  301.     $logFile = Join-Path `
  302.         $env:TEMP `
  303.         "DeleteAndReplaceWallpaper.log"

  304.     $message = @(
  305.         [DateTime]::Now.ToString("yyyy-MM-dd HH:mm:ss")
  306.         $_.Exception.ToString()
  307.         ""
  308.     ) -join [Environment]::NewLine

  309.     $message |
  310.         Out-File `
  311.             -LiteralPath $logFile `
  312.             -Encoding UTF8 `
  313.             -Append

  314.     Add-Type -AssemblyName System.Windows.Forms

  315.     [System.Windows.Forms.MessageBox]::Show(
  316.         "Operation failed.`r`n`r`n" +
  317.         $_.Exception.Message +
  318.         "`r`n`r`nLog: " +
  319.         $logFile,
  320.         "Delete and replace wallpaper",
  321.         [System.Windows.Forms.MessageBoxButtons]::OK,
  322.         [System.Windows.Forms.MessageBoxIcon]::Error
  323.     ) | Out-Null

  324.     exit 1
  325. }
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|批处理之家 ( 渝ICP备10000708号 )

GMT+8, 2026-7-26 04:24

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表