熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> 嵌入式開發 >> 正文

用批處理實現文件備份器V2.3

2022-06-13   來源: 嵌入式開發 

  復制代碼 代碼如下:

  @echo off
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
::    文件備份器V(for WinXP only)  Code by JM   QQ:
::    出處
::
::  功能自由指定要備份的目錄(或文件)位置備份時間和任務名稱
::        能檢測輸入是否正確
::        能生成備份日志
::        能多次添加備份任務
::        能批量停止指定的備份任務
::        能自動刪除由本程序產生且不再使用的批處理程序和注冊表信息
::        能從備份文件中恢復文件到源文件中並保持各文件的原始屬性不變
::
::  原理只有當源文件修改時間比目標文件的修改時間新時才更新文件
::
::  要修改或完善的地方
::
::      ① 統一標記是文件還是文件夾
::      ② 禁止把文件備份到本文件夾及其子文件夾中去
::
::  更新歷史
::
:: 
::
::           增加了記錄備份文件更新列表的功能進一步完善日志功能
::
:: 
::
::           因at命令只能以管理員權限運行此次更新增加了用戶權限的驗證添加了
::       xcopy的/c參數使得復制出錯的時候(盡管出現這種情況的幾率非常低)能備份
::       盡可能多的文件精簡了部分代碼
::
:: 
::
::           對提取文件屬性的代碼做了優化使得生成備份批處理的效率大大提高
::       感謝pengfei提供代碼修改了幾處錯誤和疏漏對代碼進行分塊放置以便日後
::       的維護此為V
::
::  
::
::           由於上次精簡過度代碼運行會出錯今天修改了一處致命錯誤感謝
::       pengfei的測試增加了一些操作提示和出錯檢測
::
::  
::
::           添加了備份空目錄的參數精簡了部分代碼
::  
::
::           實現了用同一條命令復制文件和文件夾修正了幾處錯誤
::  
::
::           精簡了獲取屬性的代碼感謝willsort提供
::  
::           完善了對備份後的文件進行恢復的操作使得恢復操作對文件或者文件夾
::       都適用此為V
::
::  
::           完善了對日期的檢測
::  
::           增加了恢復文件的功能對生成後的文件的屬性進行了調整此為V;
::  
::           對顯示各分區磁盤剩余空間的代碼進行了修改只顯示磁盤的剩余空間
::       而不會畫蛇添足地顯示光盤剩余空間
::  
::           增加了日期和時間輸入錯誤檢測功能(感謝bagpipe提供代碼)
::  
::           修改了查詢各分區剩余空間的代碼當磁盤卷標名為中文時也能准確排版
::       感謝willsort作深入分析並提供代碼當備份任務創建後能自動打開備份後
::       的文件夾和創建日志以便查看備份創建結果徹底刪除無用文件精簡了部
::       分代碼
::   
::           修正了一處錯誤精簡了部分代碼
::    
::           更改備份日志代碼將使備份日志體積減少近一半更改了實現文件名自動
::       完成這一功能的功能鍵(感謝electronixtar的提醒)但需要注冊表中的特定鍵
::       值為默認設置(有關討論請參考
::       tid=&fpage=)
::  
::          修改了部分代碼使得當需要每天備份的功能時避免了煩瑣的輸入增加
::      了文件名自動完成的功能(感謝willsort提出設想並提供代碼)此為V
::    
::          增加了如下功能當保存備份文件時如果要對文件夾進行追加或者覆蓋等
::      操作可先查看該文件夾下的內容再作決定補充了備份風險提示
::    
::          對備份後文件的保存位置這部分代碼進行了修改使得程序能自動適應備份
::      對象為文件和文件夾兩種情況使備份後文件夾的目錄結構得到保持感謝
::      willsort提供代碼當備份文件即將保存到一個已經存在的目錄下時增加了允
::      許追加至該目錄的選擇
::  
::          添加和修改了了如下功能可以選擇在開機時是否自動運行備份任務程序
::      開始運行本程序或者停止某項備份任務時自動刪除當前計劃任務中不再使用的
::      備份任務程序並刪除對應的注冊表鍵值以減少系統垃圾更改了備份任務程
::      序的保存位置去除了盤符小寫轉換為大寫的雞肋代碼增強了路徑輸入為空時
::      的檢測(感謝willsort提供代碼)修改了幾處錯誤精簡了部分代碼此為V
::      
::          在注冊表中( 位置是HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\
::      CurrentVersion\Run) 增添了開機自動運行備份程序的鍵值( 以備份任務名稱作
::      為鍵值) 盡可能減少錯過備份的情況如果更新了內容則備份完畢後自動打
::      開備份日志修正了幾處錯誤此為V
::      
::          完善了備份流程在列出創建備份任務的清單時可更改備份任務內容
::      創建備份任務的同時強制啟動計劃任務服務並立即作復制操作顯示各磁盤
::      分區剩余空間情況的時候增加了顯示磁盤卷標名的功能更改了注意事項界面
::      中的前景色和背景色使色調顯得明快而柔和
::      
::          增加了在每周的指定日期進行備份的功能添加了當計劃任務出錯時提交報
::      告的功能完善了日志記錄功能只有當文件更新時才會改寫日志完善了注意
::      事項中的內容增加了刪除所有計劃任務的功能此為 V 
::      
::          增加了不允許把保存路徑設置為與源文件路徑相同或者為源文件某一目錄
::      的功能添加了注意事項提示功能修正了幾處錯誤部分代碼參照中國DOS 聯
::      盟論壇() 網友bagpipe所發帖子使一些代碼得
::      到精簡此為V
::      
::          增加了把備份文件的保存目錄拖曳到窗口執行的功能增加了批量停止指定
::      備份任務的功能修改了幾處錯誤精簡了部分代碼此為V
::      
::          增加了把要備份的文件拖曳到窗口執行的功能感謝中國DOS 聯盟論壇
::      ()版主willsort提供代碼此為V
::      
::          修正了一處關鍵錯誤使得備份能順利進行下去在中國DOS 聯盟論壇
::      ()版主willsort等網友的熱心幫助下增強了程
::      序輸入錯誤檢測能力並修正了一些拼寫錯誤在此深表謝意
::      
::          修改了顯示各分區剩余空間的代碼使顯示界面的框線自動適應剩余空間條
::      目下不同長度的字符
::      
::          增添了停止指定備份任務的功能使本程序的功能進一步完善增添了將備
::      份後的文件設置為 系統+ 只讀 屬性的功能從而在一定程度上提高了備份後
::      的文件的安全修正了幾處錯誤優化了部分代碼此為V
::      
::          頭兩天的算法存在備份不完全的弊端今天把copy命令更改為xcopy 命令
::      從而使本程序能夠備份指定目錄下除空目錄之外的所有文件( 包括目錄之下還有
::      子目錄子目錄內含有文件的文件嵌套) 並使代碼得到了精簡頭兩天的代碼
::      生成備份任務批處理的時候因為自動命名的程序名稱是固定的如果有不同的
::      備份任務的話最後一次任務將把上一次的任務刪除今天把備份任務的命名改
::      為手動指定增添了多次添加備份任務的功能此為V
::      
::          增加了系統檢測功能使得該程序只能運行於XP操作系統下編寫輸入錯誤
::      檢測代碼使輸入錯誤能得到及時更改統一了交互界面看上去更加美觀
::      來想增加指定每周的某幾天進行備份操作的功能但是一直未能實現只好暫時
::      放棄留待下幾個版本解決優化了部分冗余代碼
::      
::          在對本人電腦上重要資料進行備份的時候深感手工備份的煩瑣而網上的
::      備份軟件又有諸多限制正好本人在自學DOS 批處理編程於是花了半天的時間
::      來構思本程序的核心功能編寫初步代碼此為V
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

rem if not %==$ %comspec% /f:on /c % $ && goto :eof 
:: 屏蔽掉上一句用Tab\Shift+Tab可實現同樣功能
mode con lines=
title 文件備份器文件備份器
color f
cls

rem   =========檢測系統是否支持本程序=============
:check_system
ver|find XP>nul || goto system_error

rem   =========檢測當前用戶是否具有管理員權限=============
:check_popedom
net users %username%|findstr /i \*administrator>nul||goto popedom_error
call :del_nouse

rem    =======輸入要備份文件的路徑並檢測輸入是否正確=======
:input_source
mode con lines=
cls
color f
title 文件備份器請輸入源文件路徑
echo                               ╭────────╮
echo           ╭─────────┤選擇要備份的文件├─────────╮
echo           │                  ╰────────╯                  │
echo           │                                                        │
echo           │         本程序能把指定文件在指定時間內備份到指定位     │
echo           │                                                        │
echo           │    置請把要備份的文件(或文件夾)拖曳至本窗口(推薦     │
echo           │                                                        │
echo           │    做法)或者手工輸入需要備份文件的絕對路徑或相對     │
echo           │                                                        │
echo           │    路徑(請勿輸入非法符號)然後回車確認              │
echo           │                                                        │
echo           │        自動完成文件名請按Tab\Shift+Tab可多次選擇   │
echo           │                                                        │
echo           │        為了不錯誤刪除數據使用本軟件前請查看注意      │
echo           │                                                        │
echo           │    事項!切記切記! (恢復文件請按 R )                  │
echo           │                                                        │
echo           ╰────────────────────────────╯
echo
echo            查看注意事項請按                               退出請按 
echo           ──────────────────────────────
echo                                查看已存在的備份任務請按                  
echo
set source=:
set /p source=           請輸入要備份文件的路徑
set source=%source:=%
:: 上面這句為判斷%source%中是否存在引號有則剔除
if %source%==: goto input_source
if %source%== exit
if %source%== goto notice
if %source%== goto backup_task
if /i %source%==r goto revert
if not exist %source% goto source_noexist
for %%i in (%source%) do if %%~fi==%%~di\ goto forbid_to_backup
:: 判斷要備份的是文件還是文件夾為以後的操作設置標志
pushd %source%>nul >nul && (popd & set folder=yes)||(set folder=)
goto input_destination


:backup_task
cls
color f
title 文件備份器已存在的備份任務
echo
at
echo 
echo
echo         ╔══════════════════════════════╗
echo         ║ 如果要停止某個備份任務請輸入該任務的ID號然後按回車即可 ║
echo         ║                                                            ║
echo         ║       多個ID號之間用空格分隔停止所有計劃任務請按 A       ║
echo         ║                                                            ║
echo         ║     退出請按  返回上一步請按除A和ID數字之外的任意鍵  ║
echo         ╚══════════════════════════════╝
echo
set ID=
set /p ID=           請輸入不再需要的備份任務的ID
if %ID%== exit
if /i %ID%==a at /delete /yes && (call :del_nouse && goto backup_task)
:: 以下語句的作用是如果停止了某項備份任務則檢查硬盤上由本程序生成的bat文件中
:: 不在at任務列表中的有哪些如果有則刪除該bat同時刪除注冊表中對應的字符串值
:: 如果沒有則不作任何刪除操作
(for %%i in (%ID%) do at %%i /del /yes >nul >nul) && (
    call :del_nouse
    goto backup_task
) || goto input_source

rem    =======輸入文件保存路徑並檢測輸入是否正確=======
:input_destination
cls
color f
title 文件備份器請輸入目標文件路徑
echo
echo
echo                               ╭────────╮
echo           ╭─────────┤  選擇保存位置  ├─────────╮
echo           │                  ╰────────╯                  │
echo           │        操作說明                                      │
echo           │                                                        │
echo           │            請輸入保存位置的絕對路徑或者相對路徑        │
echo           │                                                        │
echo           │        (注意必須在半角狀態下輸入冒號和反斜槓       │
echo           │                                                        │
echo           │        請勿輸入非法的路徑名符號)或者把一個已         │
echo           │                                                        │
echo           │        存在的文件夾拖曳至本窗口然後回車確認        │
echo           │                                                        │
echo           │          ╭────────────────╮          │
echo           ╰─────┤  查看各磁盤分區剩余空間請按   ├─────╯
echo                       ╰────────────────╯
echo
echo            返回上一步請按                                 退出請按 
echo           ──────────────────────────────
echo
set destination=:
set /p destination=           請輸入備份文件的保存路徑
set destination=%destination:=%
:: 上面這句為判斷%destination%中是否存在引號有則剔除
if %destination%==: goto input_destination
if %destination%== exit
if %destination%== goto input_source
if %destination%== goto freesize
:: 下面一句針對文件或文件夾取保存位置的文件名
for /d %%i in (%source%*) do set destination=%destination%\%%~nxi
for %%i in (%destination%) do set destination=%%~fi
set subarea=%destination:~%
for %%i in (%destination%) do if %%~fi==%%~di\ goto forbid_to_build_
echo %destination% | findstr /i /c:%source% && goto forbid_to_build_
if not exist %subarea%:\nul goto subarea_noexist
:: 下面一句取日志名為要備份文件(夾)的文件名
for %%i in (%source%) do set name_log=%%~ni
if exist %destination%\%name_log%_loglog goto whether_add
if exist %destination% goto whether_over

:over_write
attrib /s /d %destination%\**>nul >nul
rd /q /s %destination%>nul >nul
md %destination%>nul >nul
(echo
echo                                 備份日志)>%destination%\%name_log%_loglog
attrib /s /d +s +r %destination%\**>nul >nul

:input_date
cls
color f
title 文件備份器請輸備份入日期
echo                               ╭────────╮
echo           ╭─────────┤ 請輸入備份日期 ├─────────╮
echo           │                  ╰────────╯                  │
echo           │                                                        │
echo           │        若在每月的某幾天備份請輸入從的任意     │
echo           │                                                        │
echo           │    數字比如若只在每月號備份請輸入   │
echo           │                                                        │
echo           │        若在每周的某幾天備份請輸入星期幾的代碼      │
echo           │                                                        │
echo           │    (MTWThFSSu)如果指定日期較多在查看任務     │
echo           │                                                        │
echo           │    列表的時候日期一欄將用省略號顯示                │
echo           │                                                        │
echo           │        數字與字母不可混用數字行或字母行首尾均無    │
echo           │                                                        │
echo           │    任何符號其間用逗號分隔請嚴格按照本格式填寫!    │
echo           │                                                        │
echo           ╰────────────────────────────╯
echo
echo            返回上一步請按                                 退出請按 
echo           ──────────────────────────────
echo                                   每天都備份請按 A
echo
set copydate=
set /p copydate=          請輸入備份日期
if %copydate%== goto input_date
if %copydate%== goto input_date
if %copydate%== exit
if %copydate%== goto input_destination
if %copydate%== goto input_time
if /i %copydate%==a goto all_date
:: 檢查日期輸入是否正確
set num=
set char=%copydate%
for /f tokens= delims= %%i in (%char%) do (
    echo %%i|findstr /i M T W Th F S Su>nul && goto check_alphabetical_date|| goto check_numerical_date
)

:check_alphabetical_date
call :check_alp
:loop_alp
set char=%char:*=%
:check_alp
for /f tokens= delims= %%i in (%char%) do (
    echo M T W Th F S Su|findstr /i %%i>nul || goto date_error
    echo %char%|find >nul && goto loop_alp
)
goto input_time

:check_numerical_date
call :check_num
:loop_num
set /a num+=
set char=%char:*=%
:check_num
for /f tokens= delims= %%i in (%char%) do set input=%%i
if %input% GTR  goto date_error
if %num% GTR  goto date_error
echo %char%|find >nul || if %num% LEQ  goto input_time || goto date_error
goto loop_num

:input_time
cls
color f
title 文件備份器請輸入時間
echo
echo                               ╭────────╮
echo           ╭─────────┤ 請輸入備份時間 ├─────────╮
echo           │                  ╰────────╯                  │
echo           │        操作說明                                      │
echo           │                                                        │
echo           │            請按格式輸入備份時間多個時間用空格        │
echo           │                                                        │
echo           │        分隔該時間用小時制(既從::)        │
echo           │                                                        │
echo           │        的小時:分鐘格式表示                           │
echo           │                                                        │
echo           │            例如想分別在上午分和下午點進        │
echo           │                                                        │
echo           │        行備份請在同一行輸入: :(注意兩       │
echo           │                                                        │
echo           │        個時間點之間有一個空格)                         │
echo           │                                                        │
echo           ╰────────────────────────────╯
echo
echo            返回上一步請按                                 退出請按 
echo           ──────────────────────────────
echo
set copytime=
set /p copytime=           請輸入備份時間
if %copytime%== goto input_time
if %copytime%== exit
if %copytime%== goto input_date
:: 檢查時間輸入是否正確
for /f tokens=* %%i in (%copytime%) do set char=%%i
call :check_time
set num=
:back
set /a num+=
set char=%char:* =%
:check_time
for /f tokens= delims=: %%i in (%char%) do (
    if %%i GTR  goto time_error
    if %%j GTR  goto time_error
    echo %char%|find  >nul || goto input_name
)
goto back

rem    =======輸入備份任務名稱=======
:input_name
cls
color f
title 文件備份器備份任務名稱
echo
echo                               ╭────────╮
echo           ╭─────────┤  備份任務名稱  ├─────────╮
echo           │                  ╰────────╯                  │
echo           │        操作說明                                      │
echo           │                                                        │
echo           │            請輸入備份任務的名稱然後回車確認        │
echo           │                                                        │
echo           │        本程序將在系統安裝盤:\Program Files\備份       │
echo           │                                                        │
echo           │        任務程序下生成備份任務名稱_backupbat        │
echo           │                                                        │
echo           │        和備份任務名稱_revertbat這一對備份及恢       │
echo           │                                                        │
echo           │        復批處理如需更改此備份任務的部分功能        │
echo           │                                                        │
echo           │        請用文本編輯工具對批處理文件進行編輯          │
echo           │                                                        │
echo           ╰────────────────────────────╯
echo
echo            返回上一步請按                                 退出請按 
echo           ──────────────────────────────
echo
echo
set name=
set /p name=           請輸入備份任務的名稱
if %name%== goto input_name
if %name%== exit
if %name%== goto input_time
if exist %ProgramFiles%\備份任務程序\%name%_backupbat goto name_exist

call :list
echo         ╔══════════════════════════════╗
echo         ║  退出請按  返回上一步請按  放棄並開始新的備份請按 B  ║
echo         ║                                                            ║
echo         ║             繼續下一步請按除和B之外的任意鍵            ║
echo         ╚══════════════════════════════╝
echo
set choice=
set /p choice=       請選擇操作代碼(//B/其他鍵):
if %choice%== exit
if %choice%== goto input_name
if /i %choice%==b (
    attrib /s /d %destination%\**>nul >nul
    rd /q /s %destination%>nul >nul
    goto input_source
)
goto build_backup

:notice
cls
mode con lines=
color e
title 文件備份器注意事項
echo
echo
echo     ╔══════════════════════════════════╗
echo     ║                                                                    ║
echo     ║         當程序提示某路徑已存在時強烈建議在作出覆蓋操作前先查   ║
echo     ║                                                                    ║
echo     ║    看該目錄下的內容以免程序錯誤刪除該目錄下的所有內容給您帶    ║
echo     ║                                                                    ║
echo     ║    災難性的損失備份有風險操作請謹慎!                          ║
echo     ║                                                                    ║
echo     ║         路徑名中除了允許冒號和反斜槓符號緊跟盤符之外其他位   ║
echo     ║                                                                    ║
echo     ║    置不能再含有半角狀態下的以下個符號分別為\/:*?   ║
echo     ║                                                                    ║
echo     ║    <>()|輸入其中任意一個符號都會引起無法預料的錯    ║
echo     ║                                                                    ║
echo     ║    誤在本程序中文件名的命名也應遵守以上規定!                  ║
echo     ║                                                                    ║
echo     ║         如果只輸入盤符+冒號格式的路徑程序會把路徑當作指定    ║
echo     ║                                                                    ║
echo     ║    盤的當前路徑來處理而不是指定盤的根目錄比如假設系統安裝    ║
echo     ║                                                                    ║
echo     ║    在C盤在路徑中只輸入 C: 則並不會認為是C盤根目錄而是C盤的   ║
echo     ║                                                                    ║
echo     ║    當前路徑默認為C:\ducuments and settings\當前用戶名        ║
echo     ║                                                                    ║
echo     ║         如果輸入的路徑不帶盤符則作為相對路徑處理             ║
echo     ║                                                                    ║
echo     ║         本程序工作原理為通過比較備份後文件與源文件的時間早晚   ║
echo     ║                                                                    ║
echo     ║    來決定是否進行復制操作因此任何改動備份後文件修改時間的操    ║
echo     ║                                                                    ║
echo     ║    作都會使程序不能及時更新源文件改動過的數據請勿對備份後的文件  ║
echo     ║                                                                    ║
echo     ║    進行改名添加或刪除子文件等操作!                              ║
echo     ║                                                                    ║
echo     ╚══════════════════════════════════╝
echo
echo                                                      按任意鍵返回上一步
pause>nul
goto input_source

:whether_over
cls
color c
title 文件備份器路徑已存在
echo
echo
echo
echo
echo
echo ________________________________________________________________________________
echo
echo          您輸入的路徑%destination%已經存在覆蓋還是追加?
echo
echo ________________________________________________________________________________
echo
echo     ╔══════════════════════════════════╗
echo     ║   按O覆蓋按A追加按V查看保存目錄按  返回上一步按  退出    ║
echo     ╚══════════════════════════════════╝
echo
echo
set choice=
set /p choice=                           請選擇(O/A/V//): 
if /i %choice%==o cls && goto over_write
if /i %choice%==a goto input_date
if /i %choice%==v call :view_directory && goto whether_over
if %choice%== exit
if %choice%== goto input_destination
goto whether_over

:whether_add
cls
color c
title 文件備份器路徑已存在
echo
echo
echo
echo
echo
echo ________________________________________________________________________________
echo
echo          %destination%下似乎已經存在以前的備份覆蓋還是追加?
echo
echo ________________________________________________________________________________
echo
echo    ╔═══════════════════════════════════╗
echo    ║  按 V 查看保存目錄按 O 覆蓋按 A 追加按  返回上一步按  退出 ║
echo    ╚═══════════════════════════════════╝
echo
echo
set choice=
set /p choice=                           請選擇(V/O/A//): 
if /i %choice%==o goto over_write
if /i %choice%==a cls && goto input_date
if /i %choice%==v call :view_directory && goto whether_add
if %choice%== exit
if %choice%== goto input_destination
goto whether_add

:freesize
::     假設字符串freesize長度范圍為~(假設硬盤最大G換算成以M為單位則是位數)
::  則首先在freesize前補足個空格然後直接取字符串的後個字符即可得到右對齊排列
::  的數字freesize同理假設字符串volume的長度范圍為~(卷標名最長可達但是
::  為了兼顧排版的顯示只取後位)
cls
color e
title 文件備份器各分區剩余空間情況
setlocal EnableDelayedExpansion
echo
echo
echo        ╔══════════════════════════════╗
echo        ║        磁盤分區         磁盤卷標名      剩余空間(MB)       ║
echo        ║    _____________________________________________________   ║
for %%d in (C D E F G H I J K L M N O P Q R S T U V W X Y Z) do (
  if exist %%d:\nul (
    for /f tokens= %%z in (dir /c %%d:\) do set freesize=%%z
      if not !freesize!== (
        set /a freesize=!freesize:~!/>nul
        set freesize=       !freesize!
        set freesize=!freesize:~!
        for /f tokens=* %%v in (vol %%d:) do set volume=%%w
        set volume=                    !volume!
        set volume=!volume:~!
        echo        ║           %%d: !volume!     !freesize!              ║
      )
    )
)
echo        ╚══════════════════════════════╝
echo
echo
echo
echo
echo                                                按任意鍵返回上一步
pause>nul
goto input_destination

rem  ========創建備份任務腳本程序要考慮到生成多個批處理文件的情況=============
:build_backup
call :list
title 文件備份器正在生成備份程序
if not exist %ProgramFiles%\備份任務程序 md %ProgramFiles%\備份任務程序
set batch_directory=%ProgramFiles%\備份任務程序
attrib /s /d %batch_directory%\**>nul >nul

:: 因為把所有的批處理內容只用一句 >%batch_directory%\%name%_backupbat 來接收
:: 所以其中的括號都要用 ^ 來轉義

(
echo @echo off
echo mode con cols= lines=
echo color f
echo title 文件備份器%name%_backup
echo
echo rem                        功能說明
echo
echo rem        本程序由文件備份器V生成  Code by JM   QQ:
echo
echo rem                 build on %date% %time:~% by %username%
echo
echo rem    原理比較原始文件和備份文件修改日期的早晚如果原始文件修改時間晚於備份文件
echo rem          則復制原始文件覆蓋備份文件如果時間沒差別則不作任何處理
echo
echo if not exist %source% ^(
echo title 文件丟失
echo color c
echo echo
echo echo ___________________________________
echo echo
echo echo 文件%source%
echo echo
echo ecoh 不存在可能已被改名移動或者刪除
echo echo
echo echo ___________________________________
echo ping   ^>nul
echo exit^)
echo if not exist %destination% md %destination%
)>%batch_directory%\%name%_backupbat

set xcopy_parameter=
if %folder%==yes (set xcopy_parameter=/e /s) else (goto file_backup)

(
echo attrib /s /d %destination%\**^>nul ^>nul
echo set times=
echo setlocal enabledelayedexpansion
echo for /f delims= %%%%i in ^(xcopy /c /d /h /i /g /r %xcopy_parameter% /x /y %source% %destination%^) do ^(
echo     if %%%%i==復制了  個文件 ^(exit^) else ^(
echo         if not defined times call :head
echo         if ^^!file_time^^! lss %%%%~ti set file_time=%%%%~ti^&set file_route=%%%%~dpnxi
echo         if not %%%%~ti== ^(echo     %%%%~dpnxi    %%%%~ti^>^>%destination%\%name_log%_loglog
echo         ^) else ^(echo^&echo                                                %%%%i^)^>^>%destination%\%name_log%_loglog
echo     ^)
echo     if %%%%i==復制了  個文件 goto end
echo ^)

echo ^(
echo echo
echo echo     最後更新的文件是%%file_route%% 更新操作發生在 %%file_time%% 
echo ^)^>^>%destination%\%name_log%_loglog
echo :end
echo attrib /s /d +s +r %destination%\**^>nul ^>nul
echo start  %destination%\%name_log%_loglog
echo goto :eof
echo
)>>%batch_directory%\%name%_backupbat
call :build_head
goto build_revert

:file_backup
(
echo xcopy /c /d /h /i /g /q /x /y %source% %destination%^|findstr /b /e /c:復制了  個文件^>nul^&^&goto :eof
echo attrib %destination%\**^>nul ^>nul
echo echo^>^>%destination%\%name_log%_loglog
echo for /f skip= tokens= %%%%i in ^(dir /ad /tw %source%^^^|find ^) do ^(
echo     echo ^^^<%%date:~%% %%time:~%% 備份記錄^^^> 文件最後一次更新時間%%%%i %%%%j^>^>%destination%\%name_log%_loglog
echo ^)
echo attrib +s +r %destination%\**^>nul ^>nul
echo start  %destination%\%name_log%_loglog
)>>%batch_directory%\%name%_backupbat

rem  ========創建文件恢復腳本程序========
:build_revert
:: 恢復備份後文件(夾)的完整路徑
for %%i in (%source%) do set SourceFileName=%%~nxi
:: 判斷%source%是文件還是文件夾
if %folder%==yes (set SourceFiles=%destination%) else (set SourceFiles=%destination%\%SourceFileName%)
(
echo @echo off
echo mode con lines=
echo color f
echo title 文件備份器%name%_revert
echo
echo rem                        功能說明
echo
echo rem        本程序由文件備份器V生成  Code by JM   QQ:
echo
echo rem                 build on %date% %time:~% by %username%
echo
echo rem    原理在創建備份任務時把源文件的原始屬性記錄下來當需要恢復文件時
echo rem          則復制備份後的文件覆蓋源文件並去掉覆蓋後所有文件的屬性最後
echo rem          從恢復程序中讀出原始屬性並重新設置
echo if not exist %destination% ^(
echo title 文件丟失
echo color c
echo echo
echo echo
echo echo
echo echo
echo echo
echo echo
echo echo ________________________________________________________________________________
echo echo
echo echo           文件%destination%不存在可能已被改名移動或者刪除
echo echo
echo echo ________________________________________________________________________________
echo ping   ^>nul
echo exit^)
echo echo
echo echo
echo echo
echo echo
echo echo
echo echo
echo echo ________________________________________________________________________________
echo echo
echo echo          正在把文件從%destination%恢復到%source%請稍侯
echo echo
echo echo ________________________________________________________________________________
)>%batch_directory%\%name%_revertbat
if %folder%==yes echo if not exist %source% md %source%>>%batch_directory%\%name%_revertbat         
echo attrib /s /d %source%^> nul ^>nul>>%batch_directory%\%name%_revertbat

if %folder%==yes (goto folder_copy) else (goto file_copy)

:file_copy
for /f tokens=* %%i in (%source%) do (set file_root=%%~dpi)
(
echo xcopy /c /h /q /r %xcopy_parameter% /x /y %SourceFiles% %file_root%^>nul ^>nul
echo attrib %source%^>nul ^>nul
)>>%batch_directory%\%name%_revertbat
goto get_attrib

:folder_copy
(
echo xcopy /c /e /h /i /g /q /r /s /x /y %SourceFiles% %source%^>nul ^>nul
echo del /a /f %source%\%name_log%_loglog^>nul ^>nul
)>>%batch_directory%\%name%_revertbat

rem  ========獲取文件(夾)的屬性=============
:get_attrib
:: 根據文件(夾)來取捨dir中的/s參數以防%suorce%為文件時多列路徑
:: 但是當%source%為文件的時候dir /a /b %source%不會顯示絕對路徑
if %folder%==yes (set dir_=dir /a /b /s %source%) else (set dir_=%source%)
setlocal enabledelayedexpansion
for /f tokens=* %%i in (%dir_%) do (
    set var=%%~ai
    set attrib_=
    if not !var:~!== set attrib_=+!var:~!
    if not !var:~!== set attrib_=!attrib_! +!var:~!
    if not !var:~!== set attrib_=!attrib_! +!var:~!
    if not !attrib_!== echo attrib !attrib_! %%i>>%batch_directory%\%name%_revertbat
)

:add_to_reg
cls
color f
title 文件備份器開機自運行選項
echo
echo                               ╭────────╮
echo           ╭─────────┤ 開機自運行選項 ├─────────╮
echo           │                  ╰────────╯                  │
echo           │        操作說明                                      │
echo           │                                                        │
echo           │            本操作即將把備份任務加入到開機自運行        │
echo           │                                                        │
echo           │        選項中若要取消開機自運行功能請在開始       │
echo           │                                                        │
echo           │        \運行中輸入msconfig打開系統配置實用       │
echo           │                                                        │
echo           │        程序啟動處取消以備份任務名稱命名的       │
echo           │                                                        │
echo           │        啟動項目或者在注冊表[HKEY_LOCAL_MACHINE\      │
echo           │                                                        │
echo           │        SOFTWARE\Microsoft\Windows\CurrentVersion\      │
echo           │                                                        │
echo           │        Run]下刪除相應的字符串值                      │
echo           │                                                        │
echo           ╰────────────────────────────╯
echo
echo            接受請直接敲回車                                跳過請按 S
echo           ──────────────────────────────
echo
set choice=
set /p choice=           請輸入操作代碼(S/回車)
if /i %choice%==s goto run_at

rem  ========在注冊表中增添自啟動項以便開機時自動備份=============
reg add HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run /v %name% /t REG_SZ /d %batch_directory%\%name%_backupbat /f >nul >nul

:run_at
:: 強制啟用計劃任務服務
sc config Schedule start= AUTO >nul >nul
sc start Schedule>nul >nul
rem  ==========導入at計劃任務=========
for %%i in (%copytime%) do (
    at %%i /every:%copydate%  %batch_directory%\%name%_backupbat>nul >nul
)
attrib /s /d %destination%\**>nul >nul
(
echo
echo   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
echo
echo       於%date% %time:~%創建了備份任務
echo       備份對象%source%
echo       備份文件保存位置%destination%
echo       備份程序位置%batch_directory%\%name%_backupbat
echo       文件恢復程序位置%batch_directory%\%name%_revertbat
echo
echo   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
echo
echo ________________________________________________________________________________
)>>%destination%\%name_log%_loglog

cls
color f
title 文件備份器備份中……
echo
echo
echo
echo
echo
echo
echo                               ╭────────╮
echo           ╭─────────┤  正在備份文件  ├─────────╮
echo           │                  ╰────────╯                  │
echo           │        操作說明                                      │
echo           │                                                        │
echo           │            備份時間和文件大小文件數量成正比請      │
echo           │                                                        │
echo           │        耐心等待……                                    │
echo           │                                                        │
echo           ╰────────────────────────────╯
xcopy /c /h /i /g /q /r %xcopy_parameter% /x /y %source% %destination%>nul >nul
attrib /s /d +s +r %destination%\**>nul >nul

::  添加當計劃任務出錯時提交報告的功能
:: 
:: 當使用計劃任務讓系統自動運行一些命令或程序時如果運行時發生錯誤
:: 在系統的默認設置裡計劃任務不會提交錯誤報告
:: 此設置就是讓計劃任務在出現錯誤時彈出提示信息
:: 要禁用此功能請刪除注冊表中SchedulingAgent下的 NotifyOnTaskMiss
:: 
:: reg add HKLM\SOFTWARE\Microsoft\SchedulingAgent /v NotifyOnTaskMiss /t REG_DWORD /d  /f >nul >nul

cls
title 備份日志
echo
echo
type %destination%\%name_log%_loglog
echo
echo
echo
echo                                                        按任意鍵繼續
pause>nul

cls
title 備份任務列表
echo
echo
echo
echo
echo
echo
echo ________________________________________________________________________________
echo
for %%i in (%copytime%) do (
    echo          已經添加了每月^(周^) %copydate% 日 %%i 對%source%的備份任務
)
echo
echo ________________________________________________________________________________
echo
echo                     如要繼續添加備份任務請輸入 B 其他任意鍵退出
echo
echo
set again=
set /p again=                             請選擇下一步操作代碼: 
if /i %again%==b goto input_source
exit

rem  ========刪除不再使用的文件或目錄=============
:del_nouse
:: 以下語句的作用是如果停止了某項備份任務則檢查硬盤上由本程序生成的bat文件中
:: 不在at任務列表中的有哪些如果有則刪除該bat同時刪除注冊表中對應的字符串值
:: 如果沒有則不作任何刪除操作
:: 如果由本程序在%ProgramFiles%下創建的目錄為空則刪除該目錄
attrib %ProgramFiles%\備份任務程序\*bat>nul >nul
setlocal enabledelayedexpansion
for %%i in (%ProgramFiles%\備份任務程序\*_backupbat) do (
    set full_name=%%i
    set part_name=!full_name:~!
    at|find /i %%i>nul || find /i Code by JM !part_name!*bat>nul && (
        del /f /q !part_name!*bat
        reg delete HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run /v %%~fi /f >nul >nul
    )
)
for %%i in (%ProgramFiles%\備份任務程序\*bat) do (
    find /i Code by JM %%i>nul && attrib +r %%i
)
if not exist %ProgramFiles%\備份任務程序 goto :eof
dir /a /b %ProgramFiles%\備份任務程序|findstr >nul || rd /q %ProgramFiles%\備份任務程序
goto :eof


:: ━━━━━━━━━━━━━━━━━以下代碼為出錯提示━━━━━━━━━━━━━━━━━

:system_error
cls
color c
title 文件備份器操作系統不支持
echo
echo
echo
echo
echo
echo
echo                               ╭────────╮
echo           ╭─────────┤ 操作系統不支持 ├─────────╮
echo           │                  ╰────────╯                  │
echo           │                                                        │
echo           │                                                        │
echo           │         非常抱歉該程序只能在XP環境下運行             │
echo           │                                                        │
echo           │                     程序即將退出                    │
echo           │                                                        │
echo           ╰────────────────────────────╯
ping   >nul && goto :eof

:popedom_error
cls
color c
title 文件備份器權限不足
echo
echo
echo
echo
echo
echo
echo                               ╭────────╮
echo           ╭─────────┤    權限不足    ├─────────╮
echo           │                  ╰────────╯                  │
echo           │                                                        │
echo           │                                                        │
echo           │                                                        │
echo           │      非常抱歉當前用戶權限太低無法運行本程序        │
echo           │                                                        │
echo           │      請換用具備管理員組權限的其他用戶帳號來運行        │
echo           │                                                        │
echo           │                    按任意鍵退出                     │ 
echo           │                                                        │
echo           ╰────────────────────────────╯
pause>nul
goto :eof

:subarea_noexist
cls
color c
title 文件備份器磁盤 %subarea% 不存在
echo
echo
echo
echo
echo
echo                               ╭────────╮
echo           ╭─────────┤ 磁盤分區不存在 ├─────────╮
echo           │                  ╰────────╯                  │
echo           │                                                        │
echo           │                                                        │
echo           │                盤符為 %subarea% 的磁盤分區不存在               │
echo           │                                                        │
echo           │             按任意鍵返回上一步重新選擇路徑             │
echo           │                                                        │
echo           ╰────────────────────────────╯
echo
pause>nul
goto input_destination

:source_noexist
cls
color c
title 文件備份器文件不存在
echo
echo
echo
echo
echo
echo                               ╭────────╮
echo           ╭─────────┤   文件不存在   ├─────────╮
echo           │                  ╰────────╯                  │
echo           │                                                        │
echo           │                                                        │
echo           │                   要備份的文件不存在                   │
echo           │                                                        │
echo           │               按任意鍵返回上一步重新選擇               │
echo           │                                                        │
echo           ╰────────────────────────────╯
echo
pause>nul
goto input_source

:forbid_to_backup
cls
color c
title 文件備份器禁止備份
echo
echo
echo
echo
echo
echo                               ╭────────╮
echo           ╭─────────┤    禁止備份    ├─────────╮
echo           │                  ╰────────╯                  │
echo           │                                                        │
echo           │                                                        │
echo           │                  本程序不支持全盤備份                  │
echo           │                                                        │
echo           │               按任意鍵返回上一步重新選擇               │
echo           │                                                        │
echo           ╰────────────────────────────╯
echo
pause>nul
goto input_source

:forbid_to_build_
cls
color c
title 文件備份器禁止創建
echo
echo
echo
echo
echo
echo                               ╭────────╮
echo           ╭─────────┤    禁止創建    ├─────────╮
echo           │                  ╰────────╯                  │
echo           │                                                        │
echo           │                                                        │
echo           │         為了數據的安全請勿直接備份到根目錄下         │
echo           │                                                        │
echo           │               按任意鍵返回上一步重新選擇               │
echo           │                                                        │
echo           ╰────────────────────────────╯
echo
pause>nul
goto input_destination

:forbid_to_build_
cls
color c
title 文件備份器禁止創建
echo
echo
echo
echo
echo
echo                               ╭────────╮
echo           ╭─────────┤    禁止創建    ├─────────╮
echo           │                  ╰────────╯                  │
echo           │                                                        │
echo           │        警告保存位置與要備份文件的位置路徑相同        │
echo           │                                                        │
echo           │              或者位於要備份文件的某一目錄下            │
echo           │                                                        │
echo           │            為了數據的安全請重新選擇保存位置          │
echo           │                                                        │
echo           │               按任意鍵返回上一步重新選擇               │
echo           │                                                        │
echo           ╰────────────────────────────╯
echo
pause>nul
goto input_destination

:destination_input_erro
cls
color c
title 文件備份器路徑輸入錯誤
echo
echo
echo
echo
echo
echo                               ╭────────╮
echo           ╭─────────┤  路徑輸入錯誤  ├─────────╮
echo           │                  ╰────────╯                  │
echo           │                                                        │
echo           │                                                        │
echo           │                   您的路徑輸入有錯誤                   │
echo           │                                                        │
echo           │              請在半角狀態輸入冒號和反斜槓              │
echo           │                                                        │
echo           │               按任意鍵返回上一步重新選擇               │
echo           │                                                        │
echo           ╰────────────────────────────╯
echo
pause>nul
goto input_destination

:date_error
cls
color c
title 文件備份器日期輸入錯誤
echo
echo                               ╭────────╮
echo           ╭─────────┤  日期輸入錯誤  ├─────────╮
echo           │                  ╰────────╯                  │
echo           │                                                        │
echo           │                   您的日期輸入有錯誤                   │
echo           │                                                        │
echo           │                                                        │
echo           │         日期不能字母和數字混用                     │
echo           │                                                        │
echo           │         單個的數字式日期不能大於個數不能超過     │
echo           │                                                        │
echo           │                                                  │
echo           │                                                        │
echo           │         字母式的日期只能是 MTWThFSSu 中的      │
echo           │                                                        │
echo           │    任意幾個不區分大小寫                            │
echo           │                                                        │
echo           │         日期之間只能用逗號分隔                     │
echo           │                                                        │
echo           │                                                        │
echo           │               按任意鍵返回上一步重新選擇               │
echo           │                                                        │
echo           ╰────────────────────────────╯
pause>nul
goto input_date

:time_error
cls
color c
title 文件備份器時間輸入錯誤
echo
echo
echo
echo
echo
echo                               ╭────────╮
echo           ╭─────────┤  時間輸入錯誤  ├─────────╮
echo           │                  ╰────────╯                  │
echo           │                                                        │
echo           │                                                        │
echo           │                   您的時間輸入有錯誤                   │
echo           │                                                        │
echo           │小時數不能大於分鐘數不能大於每個時間點用空格分隔│
echo           │                                                        │
echo           │               按任意鍵返回上一步重新選擇               │
echo           │                                                        │
echo           ╰────────────────────────────╯
echo
pause>nul
goto input_time

:name_exist
cls
color c
title 文件備份器同名程序 %name%_backupbat 已經存在
echo
echo
echo
echo
echo
echo                               ╭────────╮
echo           ╭─────────┤  存在同名程序  ├─────────╮
echo           │                  ╰────────╯                  │
echo           │                                                        │
echo           │                                                        │
echo           │ %ProgramFiles%\備份任務程序下已存在同名的批處理程序│
echo           │                                                        │
echo           │               按任意鍵返回上一步重新選擇               │
echo           │                                                        │
echo           ╰────────────────────────────╯
echo
pause>nul
goto input_name

:: ━━━━━━━━━━━━━━━━━以下代碼為被調用的子過程━━━━━━━━━━━━━━━━━

rem  ========查看保存位置下的內容以決定 追加/覆蓋/重新選擇 等操作========
:view_directory
explorer %destination%
goto :eof

rem  ========簡化每天都需要備份時的操作========
:all_date
set copydate=
goto input_time
goto :eof

rem  ========從備份文件中恢復文件========
:revert
explorer %ProgramFiles%\備份任務程序
goto input_source
goto :eof

rem  ========顯示備份清單========
:list
cls
color f
title 文件備份器備份清單
echo
echo ________________________________________________________________________________
echo
echo                         備份任務名稱%name%
echo
echo                         要備份的文件%source%
echo
echo                         保存位置%destination%
echo
echo                         備份日期 %copydate%
echo
echo                         備份時間%copytime%
echo
echo ________________________________________________________________________________
echo
goto :eof

rem  ========日志裡的更新列表頭========
:build_head
(
echo :head
echo set times=
echo ^(
echo echo _____________________________________________________________________________________
echo echo
echo echo *更新列表^^^(%%date:~%% %%time:~%%^^^):
echo echo
echo ^)^>^>%destination%\%name_log%_loglog
echo goto :eof
)>>%batch_directory%\%name%_backupbat
goto :eof


From:http://tw.wingwit.com/Article/program/qrs/201401/30218.html
    推薦文章
    Copyright © 2005-2022 電腦知識網 Computer Knowledge   All rights reserved.