不求甚解

此博客为个人学习之用,如与其他作品雷同,纯属巧合。

导航

Desktop_Cleaner.bat

桌面整理自动化工具。它通过将非快捷方式的项目归档到备份文件夹,帮助用户保持桌面的整洁。它最大的特点在于自动检测真实桌面路径和自动创建登录时运行的计划任务,从而实现无人值守的定期清理。但是,它的一个显著特点是硬编码了计划任务的执行路径,这限制了其部署的灵活性。

@echo off
setlocal enabledelayedexpansion

:: --- 获取真实桌面路径 ---
echo [.] Querying real Desktop path from Registry...

:: 查询当前用户桌面路径
for /f "usebackq tokens=2*" %%a in (`reg query "HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders" /v "Desktop" 2^>nul`) do (
    set "REG_DESKTOP_PATH=%%b"
)

if not defined REG_DESKTOP_PATH (
    echo [!] ERROR: Could not find 'Desktop' path in registry. Using default USERPROFILE\Desktop.
    set "SOURCE=%USERPROFILE%\Desktop"
) else (
    :: 处理注册表路径中的环境变量(如 %USERPROFILE%)
    call set "SOURCE=!REG_DESKTOP_PATH!"
)

:: --- 设置备份目录 ---
set "DEST_ROOT=D:"
set "DEST=!DEST_ROOT!\Desktop_Backup"

:: --- 原始脚本其余部分 ---
:: (保持与原始脚本相同的逻辑,只需替换 SOURCE 变量)
echo [.] Real Desktop path detected: !SOURCE!
echo [.] Backup destination: !DEST!

:: 检查源路径是否存在
if not exist "!SOURCE!" (
    echo [ERROR] Source directory does not exist: !SOURCE!
    pause
    exit /b 1
)

if not exist "!DEST!" (
    echo [.] Creating backup directory: !DEST!
    mkdir "!DEST!"
    if errorlevel 1 (
        echo [ERROR] Failed to create backup directory: !DEST!
        pause
        exit /b 1
    )
)

:: Require admin
net session >nul 2>&1
if %errorlevel% neq 0 (
    echo [!] Please run as Administrator.
    pause
    exit /b 1
)

:: >>> CRITICAL: Use HALF-WIDTH ~ (NOT ~) to get correct path <<<
set "FULL_PATH=%~f0"  <-- (虽然这里设置了 FULL_PATH,但下面创建任务时不再使用它)

:: Only create task on interactive run (not when triggered by task)
if /i not "%~1" equ "/task" (
    echo [+] Creating scheduled task to auto-clean on user logon...
    
    :: Create task that runs at logon (reliable!)
    :: Modified line: Hardcoded path to D:\Desktop_Backup\Desktop_Cleaner.bat
    schtasks /create /tn "Clean-Desktop-Only-LNK" /tr "\"D:\Desktop_Backup\Desktop_Cleaner.bat\" /task" /sc onlogon /rl highest /f >nul
    
    if %errorlevel% equ 0 (
        echo [+] Task created successfully. Will run at every logon.
    ) else (
        echo [!] Failed to create task. Error code: %errorlevel%
        echo     Common cause: Antivirus or Group Policy blocking.
    )
    echo.
)

echo [+] Starting cleanup: keeping ONLY .lnk shortcuts on desktop: "!SOURCE!"
echo.

:: 终极修复:先保留所有 .lnk 文件,再移动非 .lnk 文件,无需提取扩展名
:: 1. 保留 .lnk 快捷方式(包括谷歌快捷方式)
echo [.] Checking for .lnk files to keep...
for /f "delims=" %%F in ('dir /a:-d /b "!SOURCE!"\*.lnk 2^>nul') do (
    echo [KEEP] %%F
)

:: 2. 移动所有非 .lnk 文件(反向匹配,精准筛选)
echo [.] Checking for non-.lnk files to move...
for /f "delims=" %%F in ('dir /a:-d /b "!SOURCE!"\* 2^>nul ^| findstr /i /v /c:".lnk"') do (
    echo [MOVE FILE] "%%F"
    move "!SOURCE!"\"%%F" "!DEST!" >nul
    if errorlevel 1 (
        echo [!] Warning: Failed to move file: "%%F"
    )
)

echo.

:: 统一路径写法,适配含空格路径 - 改进 robocopy 处理
echo [.] Checking for folders to move...
for /f "delims=" %%D in ('dir /ad /b "!SOURCE!"\* 2^>nul') do (
    echo [MOVE FOLDER] "%%D"
    set "FOLDER_NAME=%%D"
    set "SRC_FOLDER_PATH=!SOURCE!\!FOLDER_NAME!"
    set "DEST_FOLDER_PATH=!DEST!\!FOLDER_NAME!"
    
    :: 使用 pushd/popd 展开路径并执行 robocopy,避免环境变量问题
    pushd "!SRC_FOLDER_PATH!"
    if errorlevel 1 (
        echo [!] Error: Could not access source folder: "!SRC_FOLDER_PATH!"
        popd
        goto :next_folder
    )
    robocopy . "!DEST_FOLDER_PATH!" /e /move /ndl /njh /njs
    set "ROBOCOPY_ERRORLEVEL=!errorlevel!"
    popd
    
    if !ROBOCOPY_ERRORLEVEL! gtr 8 (
        echo [!] Warning: robocopy reported error level !ROBOCOPY_ERRORLEVEL! for folder: "!SRC_FOLDER_PATH!"
    )
    
    :: 尝试删除源目录(robocopy /move 应该已清空,但有时需要额外确认)
    if exist "!SRC_FOLDER_PATH!" (
        rd /s /q "!SRC_FOLDER_PATH!" >nul 2>&1
        if errorlevel 1 (
             echo [!] Warning: Failed to remove empty source folder: "!SRC_FOLDER_PATH!"
        )
    )

    :next_folder
)

echo.
echo [+] Cleanup completed. Check backup location: !DEST!

:: Pause only if run manually
if /i not "%~1" equ "/task" pause

endlocal
exit /b 0