在壁纸设置为幻灯片后,如果遇到不喜欢的壁纸,点击原本的下一个桌面背景菜单,会切换到下一张,然而这样治标不治本,以后还是会出现,使用此脚本可直接删除壁纸源文件并切换到下一张。- <#*,:
- @echo off
- chcp 65001 >nul
- rem "脚本为批处理脚本,扩展名为.bat ,编码为UTF-8。(主要代码来自AI)
- rem "用法一:直接双击脚本;
- rem "用法二:添加为桌面右键菜单,实现便捷操作。( 1.下载第三方工具nircmd ,放在systems32目录下;2.将本脚本文件永久放在某固定目录下,然后右键以管理员执行1次即可添加右键菜单; )
- rem "注意:删除壁纸操作不可逆,注意备份;用法二默认删除 Windows自带的下一个桌面背景菜单。
- set ContextMenuText=下一个桌面背景#
- cd /d "%~dp0"
- set "batchfile=%~f0"
- set psline=Powershell.exe -ExecutionPolicy Bypass -C "Set-Location -LiteralPath ([Environment]::CurrentDirectory);. ([ScriptBlock]::Create([IO.File]::ReadAllText($env:batchfile,[Text.Encoding]::GetEncoding(0) )) )"
- if "%~1" equ "r" (
- %psline%
- ) else (
- fltmc >nul 2>&1
- if not errorlevel 1 (
- reg delete "HKCU\Software\Classes\DesktopBackground\shellex\ContextMenuHandlers\DesktopSlideshow" /f >nul 2>&1
- reg delete "HKCR\DesktopBackground\shellex\ContextMenuHandlers\DesktopSlideshow" /f >nul 2>&1
- reg delete "HKCU\Software\Classes\DesktopBackground\Shell" /ve /f >nul 2>&1
- reg add "HKCU\Software\Classes\DesktopBackground\Shell\M_DeleteAndReplaceWallpaper" /v "MUIVerb" /t REG_SZ /d "%ContextMenuText%" /f
- reg add "HKCU\Software\Classes\DesktopBackground\Shell\M_DeleteAndReplaceWallpaper" /v "Position" /t REG_SZ /d "Bottom" /f
- reg add "HKCU\Software\Classes\DesktopBackground\Shell\M_DeleteAndReplaceWallpaper" /v "Icon" /t REG_SZ /d "imageres.dll,-5347" /f
- 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
- ) else (
- %psline%
- )
- )
- exit /b
- #>
- try {
- Add-Type -TypeDefinition @'
- using System;
- using System.Collections.Generic;
- using System.IO;
- using System.Runtime.InteropServices;
- using System.Threading;
- public static class WallpaperAction
- {
- [StructLayout(LayoutKind.Sequential)]
- private struct RECT
- {
- public int Left;
- public int Top;
- public int Right;
- public int Bottom;
- }
- [ComImport]
- [Guid("B92B56A9-8B55-4E14-9A89-0199BBB6F93B")]
- [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
- private interface IDesktopWallpaper
- {
- [PreserveSig]
- int SetWallpaper(
- [MarshalAs(UnmanagedType.LPWStr)] string monitorID,
- [MarshalAs(UnmanagedType.LPWStr)] string wallpaper);
- [PreserveSig]
- int GetWallpaper(
- [MarshalAs(UnmanagedType.LPWStr)] string monitorID,
- out IntPtr wallpaper);
- [PreserveSig]
- int GetMonitorDevicePathAt(
- uint monitorIndex,
- out IntPtr monitorID);
- [PreserveSig]
- int GetMonitorDevicePathCount(
- out uint count);
- [PreserveSig]
- int GetMonitorRECT(
- [MarshalAs(UnmanagedType.LPWStr)] string monitorID,
- out RECT displayRect);
- [PreserveSig]
- int SetBackgroundColor(uint color);
- [PreserveSig]
- int GetBackgroundColor(out uint color);
- [PreserveSig]
- int SetPosition(uint position);
- [PreserveSig]
- int GetPosition(out uint position);
- [PreserveSig]
- int SetSlideshow(IntPtr items);
- [PreserveSig]
- int GetSlideshow(out IntPtr items);
- [PreserveSig]
- int SetSlideshowOptions(
- uint options,
- uint slideshowTick);
- [PreserveSig]
- int GetSlideshowOptions(
- out uint options,
- out uint slideshowTick);
- [PreserveSig]
- int AdvanceSlideshow(
- [MarshalAs(UnmanagedType.LPWStr)] string monitorID,
- uint direction);
- [PreserveSig]
- int GetStatus(out uint state);
- [PreserveSig]
- int Enable(
- [MarshalAs(UnmanagedType.Bool)] bool enable);
- }
- private sealed class MonitorInfo
- {
- public string Id;
- public string Path;
- }
- private static readonly Guid DesktopWallpaperClsid =
- new Guid("C2CF3110-460E-4FC1-B9D0-8A1C0C9CC4BD");
- private static void ThrowIfFailed(int result)
- {
- if (result < 0)
- {
- Marshal.ThrowExceptionForHR(result);
- }
- }
- private static string ReadAndFreeString(IntPtr pointer)
- {
- if (pointer == IntPtr.Zero)
- {
- return String.Empty;
- }
- try
- {
- string value = Marshal.PtrToStringUni(pointer);
- return value ?? String.Empty;
- }
- finally
- {
- Marshal.FreeCoTaskMem(pointer);
- }
- }
- private static string GetMonitorId(
- IDesktopWallpaper desktop,
- uint index)
- {
- IntPtr pointer = IntPtr.Zero;
- ThrowIfFailed(
- desktop.GetMonitorDevicePathAt(index, out pointer)
- );
- return ReadAndFreeString(pointer);
- }
- private static string GetWallpaperPath(
- IDesktopWallpaper desktop,
- string monitorId)
- {
- IntPtr pointer = IntPtr.Zero;
- ThrowIfFailed(
- desktop.GetWallpaper(monitorId, out pointer)
- );
- return ReadAndFreeString(pointer);
- }
- public static int Run()
- {
- object comObject = null;
- try
- {
- Type comType =
- Type.GetTypeFromCLSID(
- DesktopWallpaperClsid,
- true
- );
- comObject = Activator.CreateInstance(comType);
- IDesktopWallpaper desktop =
- (IDesktopWallpaper)comObject;
- uint monitorCount = 0;
- ThrowIfFailed(
- desktop.GetMonitorDevicePathCount(
- out monitorCount
- )
- );
- if (monitorCount == 0)
- {
- throw new InvalidOperationException(
- "No monitor was found."
- );
- }
- List<MonitorInfo> monitors =
- new List<MonitorInfo>();
- HashSet<string> oldPaths =
- new HashSet<string>(
- StringComparer.OrdinalIgnoreCase
- );
- for (uint i = 0; i < monitorCount; i++)
- {
- string monitorId =
- GetMonitorId(desktop, i);
- string wallpaperPath =
- GetWallpaperPath(
- desktop,
- monitorId
- );
- if (String.IsNullOrWhiteSpace(
- wallpaperPath))
- {
- continue;
- }
- if (!File.Exists(wallpaperPath))
- {
- continue;
- }
- MonitorInfo info =
- new MonitorInfo();
- info.Id = monitorId;
- info.Path = wallpaperPath;
- monitors.Add(info);
- oldPaths.Add(wallpaperPath);
- }
- if (monitors.Count == 0)
- {
- throw new InvalidOperationException(
- "The current wallpaper source file was not found."
- );
- }
- int advanceResult =
- desktop.AdvanceSlideshow(
- null,
- 0
- );
- if (advanceResult < 0)
- {
- throw new COMException(
- "AdvanceSlideshow failed. HRESULT: 0x" +
- advanceResult.ToString("X8"),
- advanceResult
- );
- }
- HashSet<string> displayedPaths =
- new HashSet<string>(
- StringComparer.OrdinalIgnoreCase
- );
- DateTime deadline =
- DateTime.UtcNow.AddSeconds(10);
- while (DateTime.UtcNow < deadline)
- {
- displayedPaths.Clear();
- foreach (MonitorInfo monitor in monitors)
- {
- string currentPath =
- GetWallpaperPath(
- desktop,
- monitor.Id
- );
- if (!String.IsNullOrWhiteSpace(
- currentPath))
- {
- displayedPaths.Add(currentPath);
- }
- }
- bool oldImageStillDisplayed = false;
- foreach (string oldPath in oldPaths)
- {
- if (displayedPaths.Contains(oldPath))
- {
- oldImageStillDisplayed = true;
- break;
- }
- }
- if (!oldImageStillDisplayed)
- {
- break;
- }
- Thread.Sleep(200);
- }
- int deletedCount = 0;
- foreach (string oldPath in oldPaths)
- {
- if (displayedPaths.Contains(oldPath))
- {
- continue;
- }
- if (File.Exists(oldPath))
- {
- File.Delete(oldPath);
- deletedCount++;
- }
- }
- if (deletedCount == 0)
- {
- throw new InvalidOperationException(
- "The wallpaper did not change, so no file was deleted."
- );
- }
- return deletedCount;
- }
- finally
- {
- if (comObject != null &&
- Marshal.IsComObject(comObject))
- {
- Marshal.FinalReleaseComObject(
- comObject
- );
- }
- }
- }
- }
- '@ -ErrorAction Stop
- [WallpaperAction]::Run() | Out-Null
- exit 0
- }
- catch {
- $logFile = Join-Path `
- $env:TEMP `
- "DeleteAndReplaceWallpaper.log"
- $message = @(
- [DateTime]::Now.ToString("yyyy-MM-dd HH:mm:ss")
- $_.Exception.ToString()
- ""
- ) -join [Environment]::NewLine
- $message |
- Out-File `
- -LiteralPath $logFile `
- -Encoding UTF8 `
- -Append
- Add-Type -AssemblyName System.Windows.Forms
- [System.Windows.Forms.MessageBox]::Show(
- "Operation failed.`r`n`r`n" +
- $_.Exception.Message +
- "`r`n`r`nLog: " +
- $logFile,
- "Delete and replace wallpaper",
- [System.Windows.Forms.MessageBoxButtons]::OK,
- [System.Windows.Forms.MessageBoxIcon]::Error
- ) | Out-Null
- exit 1
- }
复制代码 |