使用AHK写的外壳,主要是为了配合FreeFileSync快速实现多方案的备份的
1、可以设置多个备份计划,每个备份计划里可以设置多个备份项
2、使用XML作为配置文件,避免FreeFileSync每一个备份项都要单独一个文件的问题
3、F1-F8切换到列表1-8项
4、可以备份完自动关机,放那里直接去睡觉就OK啦……
好用,谁用谁知道,哇哈哈哈哈!!!
↓↓↓↓↓↓↓↓↓↓↓↓↓下面是源码↓↓↓↓↓↓↓↓↓↓↓↓↓
/*
程序: Kawvin批处理备份(FreeFileSync)
作用: 使用FreeFileSync批量备份文件
作者: Kawvin
版本: 6.1.5_2018.12.31
使用方法:
6.1.5更新说明:增加compare比较文件夹功能
*/
Label_Init: ;{脚本前设置
#NoEnv
#SingleInstance Force
SetWorkingDir %A_ScriptDir%
;}
Label_DefVar: ;{变量定义
global MyAppVer:="Kawvin批处理备份(FreeFileSync)V6.1.5"
global BackupXML:=A_ScriptDir . "\KawvinBatchBackup.xml"
global Timeout:= ;倒计时时间
global ProjectArray:={} ;用来进行保存所有的备份计划
global Project_List:=
global Item_List:=
ReadXMLToArray(BackupXML)
;}
Label_DrawGUI: ;{绘制窗体
Menu Tray, Icon, shell32.dll, 47
;~ Gui New,+AlwaysOnTop
Gui Add, GroupBox, x5 y3 w860 h40, 【1】设置
Gui Add, Text, x15 y15 w151 h23 +0x200, FreeFileSync主程序路径:
Gui Add, Edit, x160 y15 w650 h21 vAppPath,%AppPath%
Gui Add, Button, x815 y14 w40 h23 g程序路径浏览, 浏览
Gui Font, Bold c0x0000FF
Gui Add, GroupBox, x5 y50 w320 h360, 【2】备份计划 【列表右键有惊喜】
Gui Font
Gui Add, Text, x15 y70 w55 h23 +0x200 , 备份计划:
Gui Add, DropDownList, x80 y71 w234 vProject_Sel g备份计划_变动, %Project_List%
Gui Add, Text, x15 y96 w55 h23 +0x200, 备份项目:
Gui Font, Bold c0xFF0000
Gui Add, Text, x100 y96 w200 h23 +0x200 vLastBackTime, 最近备份:
Gui Font
Gui Add, ListBox, x15 y122 w300 h280 vItem_Sel g备份项目_变动, %Item_List%
Gui Add, GroupBox, x330 y50 w535 h112, 【2.1】项目信息
Gui Add, Text, x340 y69 w60 h22 +0x200, 项目名称:
Gui Add, Edit, x405 y70 w450 h21 vItemName
Gui Add, Text, x340 y99 w60 h22 +0x200, 源文件夹:
Gui Add, Edit, x405 y100 w405 h21 vSourceDir
Gui Add, Button, x815 y99 w40 h23 g源文件夹浏览, 浏览
Gui Add, Text, x340 y129 w60 h23 +0x200, 目标目录:
Gui Add, Edit, x405 y130 w405 h21 vDirectionDir
Gui Add, Button, x815 y129 w40 h23 g目标目录浏览, 浏览
Gui Add, GroupBox, x330 y165 w320 h170, 【2.2】备份选项
Gui Add, Text, x340 y189 w57 h20 +0x200, 比较内容:
Gui Add, DropDownList, x415 y190 w220 vCompare, 文件时间和大小||文件内容|文件大小
Gui Add, Text, x340 y219 w57 h20 +0x200, 备份方式:
Gui Add, DropDownList, x415 y220 w220 vSynchronize, 双向 <->||镜像 ->|更新 >
Gui Add, Text, x338 y250 w72 h20 +0x200, 进度对话框:
Gui Add, CheckBox, x415 y250 w80 h23 vProgressDialogMinimized, 最小化运行
Gui Add, CheckBox, x515 y250 w70 h23 vProgressDialogAutoClose, 自动关闭
Gui Add, Text, x340 y280 w57 h20 +0x200, 错误处理:
Gui Add, CheckBox, x415 y280 w71 h23 vErrorsIgnore, 忽略错误
Gui Add, DropDownList, x515 y280 w120 vErrorDialog, 弹出对话框|取消备份
Gui Add, Text, x340 y309 w72 h20 +0x200, 完成后操作:
Gui Add, DropDownList, x415 y310 w220 vPostSyncAction, |系统休眠|系统关机
Gui Add, GroupBox, x330 y340 w320 h70, 【3】操作
Gui Add, Button, x380 y360 w100 h40 Default g一键备份, 一键备份
Gui Font, Bold c0x0000FF
Gui Add, CheckBox, x520 y370 w95 h23 vShutdownAfterfinish, &A 完成关机
Gui Font
Gui Add, GroupBox, x655 y165 w210 h70, 【4】备份计划
Gui Add, Button, x670 y190 w85 h30 g新建计划, 4.1新建计划
Gui Add, Button, x765 y190 w85 h30 g删除计划, 4.2删除计划
Gui Add, GroupBox, x655 y255 w210 h70, 【5】备份项目
Gui Add, Button, x670 y280 w85 h30 g单个添加, 5.1单个添加
Gui Add, CheckBox, x765 y280 w90 h30 vAuto, 自动批量添加
Gui Add, GroupBox, x655 y340 w210 h70, 【6】保存
Gui Add, Button, x670 y365 w85 h30 g确认修改, 确认修改
Gui Add, Button, x765 y365 w85 h30 g保存到XML, 保存到XML
;~ Gui Add, Progress, x190 y420 w500 h23 -Smooth vProgress1, 0
Gui Add, Progress, x190 y420 w500 h23 -Smooth Hidden vProgress1, 0
Gui Font, c0xFF0000
Gui Add, Text, x15 y420 w40 h19 +0x200, 说明:
Gui Add, Text, x15 y445 w850 h19 +0x200, 一、①在【2.1】、【2.2】录入相关信息后;②使用【5.1单个添加】
Gui Add, Text, x15 y470 w850 h19 +0x200, 二、不勾选【自动批量添加】,①按住Ctrl,拖动【单个】目标目录到本窗体;②拖动【单个】源文件夹到本窗体;③录入项目名称后;④使用【5.1单个添加】
Gui Add, Text, x15 y495 w850 h19 +0x200, 三、勾选【自动批量添加】,①按住Ctrl,拖动【单个】目标目录到本窗体;②拖动【多个】源文件夹到本窗体;③逐个确认项目名称后自动添加
Gui Add, Text, x15 y520 w850 h19 +0x200, 四、①拖动【单个】FreeFileSync文件到本窗体,自动添加到项目列表;②拖动【多个】FreeFileSync文件到本窗体,③逐个确认输入项目名称后自动添加
Gui Font, s12 Bold
Gui Add, Text, x15 y545 w850 h25 +0x200, 五、保存:①修改已有项目,需【确认修改】;②【确认修改】或【单个添加】或【批量添加】后须【保存到XML】
Gui Font
Gui Add, Edit, x400 y490 w240 h21 vUUID Disabled Hidden
gosub,窗体初始化
GuiControl,choose,Project_Sel,1
gosub,备份计划_变动
Gui Show, w880 h580, %MyAppVer%
Return
;}
GuiEscape: ;{
GuiClose:
ExitApp
return
;}
F1::Guicontrol,Choose,Project_Sel,1 ;{ F1-F8切换到列表1-8项
F2::Guicontrol,Choose,Project_Sel,2
F3::Guicontrol,Choose,Project_Sel,3
F4::Guicontrol,Choose,Project_Sel,4
F5::Guicontrol,Choose,Project_Sel,5
F6::Guicontrol,Choose,Project_Sel,6
F7::Guicontrol,Choose,Project_Sel,7
F8::Guicontrol,Choose,Project_Sel,8
;}
程序路径浏览: ;{
FileSelectFile, AppPath, 3, , 请设定FreeFileSync程序路径, 程序 (*.exe)
if (AppPath !="")
Guicontrol,,AppPath,%AppPath%
return
;}
源文件夹浏览: ;{
;选择目录
FileSelectFolder, SourceDir, ::{20d04fe0-3aea-1069-a2d8-08002b30309d}, 3,选择目录
if (SourceDir !="")
Guicontrol,,SourceDir,%SourceDir%
return
;}
目标目录浏览: ;{
;选择目录
FileSelectFolder, DirectionDir, ::{20d04fe0-3aea-1069-a2d8-08002b30309d}, 3,选择目录
if (DirectionDir !="")
Guicontrol,,DirectionDir,%DirectionDir%
return
;}
新建计划: ;{
InputBox,MyTemInput,请输入备份计划名称,,,250,100
if (MyTemInput="")
return
if (instr(Project_List,MyTemInput)) {
MsgBox, 0, 提示, 该名称已存在,请重新输入
return
}
Project_List.= "|" MyTemInput
GuiControl,,Project_Sel,%MyTemInput%
Guicontrol,ChooseString,Project_Sel,%MyTemInput%
gosub,备份计划_变动
return
;}
删除计划: ;{
GuiControlGet,Project_Sel,,Project_Sel
MsgBox, 36, 提示, 确认删除【%Project_Sel%】备份计划及备份项目?
IfMsgBox,yes
{
loop,% ProjectArray.length()
{
aProject:=ProjectArray[A_index]
if (aProject.Name=Project_Sel) {
ProjectArray.removeat(A_index)
break
}
}
if regexmatch(Project_List, "(\|)" . Project_Sel . "(\|)")
Project_List:=RegExReplace(Project_List,"(\|)" . Project_Sel,"")
if regexmatch(Project_List, "^" . Project_Sel . "(\|)")
Project_List:=RegExReplace(Project_List,Project_Sel . "(\|)","")
if regexmatch(Project_List, "(\|)" . Project_Sel . "$")
Project_List:=RegExReplace(Project_List,"(\|)" . Project_Sel,"")
GuiControl,,Project_Sel,|
GuiControl,,Project_Sel,%Project_List%
Guicontrol,Choose,Project_Sel,1
gosub,备份计划_变动
}
return
;}
单个添加: ;{
aUUID:=UUIDCreate()
GuiControlGet,aProject_Sel,,Project_Sel
GuiControlGet,aItemName,,ItemName
GuiControlGet,aCompare,,Compare
GuiControlGet,aSynchronize,,Synchronize
GuiControlGet,aSourceDir,,SourceDir
GuiControlGet,aDirectionDir,,DirectionDir
GuiControlGet,aErrorsIgnore,,ErrorsIgnore
GuiControlGet,aProgressDialogMinimized,,ProgressDialogMinimized
GuiControlGet,aProgressDialogAutoClose,,ProgressDialogAutoClose
GuiControlGet,aErrorDialog,,ErrorDialog
GuiControlGet,aPostSyncAction,,PostSyncAction
if(aItemName="" or aSourceDir="" or aDirectionDir="") {
MsgBox, 0, 提示, 【项目名称】或【源文件夹】或【目标目录】为空,请重新输入
return
}
if (aCompare="文件时间和大小")
aCompare:="TimeAndSize"
else if (aCompare="文件内容")
aCompare:="Content"
else if (aCompare="文件大小")
aCompare:="Size"
if (aSynchronize="双向 <->")
aSynchronize:="TwoWay"
else if (aSynchronize="镜像 ->")
aSynchronize:="Mirror"
else if (aSynchronize="更新 >")
aSynchronize:="Update"
if (aErrorDialog="取消备份")
aErrorDialog:="Cancel"
else
aErrorDialog:="Show"
if (aPostSyncAction="系统休眠")
aPostSyncAction:="Sleep"
else if (aPostSyncAction="系统关机")
aPostSyncAction:="Shutdown"
else
aPostSyncAction:="None"
aErrorsIgnore:=cBool(aErrorsIgnore)
aProgressDialogMinimized:=cBool(aProgressDialogMinimized)
aProgressDialogAutoClose:=cBool(aProgressDialogAutoClose)
aBackupItem:=new BackupItem(aUUID,aItemName,aCompare,aSynchronize,aSourceDir,aDirectionDir,aErrorsIgnore,aProgressDialogMinimized,aProgressDialogAutoClose,aErrorDialog,aPostSyncAction)
HasProject:=0
loop,% ProjectArray.length()
{
if (ProjectArray[A_index].Name=aProject_Sel){
ProjectArray[A_index].Items.push(aBackupItem)
HasProject:=1
break
}
}
if (!HasProject) {
Project:={}
Project.Items:={}
Project.Name:=aProject_Sel
Project.LastBuckupTime:=""
Project.Items.push(aBackupItem)
ProjectArray.push(Project)
}
Item_List.= "|" aItemName
GuiControl,,Item_Sel,|
GuiControl,,Item_Sel,%Item_List%
GuiControl,ChooseString,Item_Sel,%aItemName%
return
;}
GuiDropFiles: ;{拖拽文件到窗体
GuiControlGet,aProject_Sel,,Project_Sel
if (aProject_Sel=""){
MsgBox, 0, 提示, 请先创建备份计划!
return
}
MySel:=A_GuiEvent
;【1】判断是单文件还是多文件
if (instr(MySel,"`n")){ ;多文件
Loop,parse,MySel,`n,`r
{
if (A_LoopField="")
continue
If InStr(FileExist(A_LoopField), "D") { ;区分是否文件夹,Attrib= D ,则是文件夹
GuiControlGet,DirectionDir,,DirectionDir
if (DirectionDir=""){
MsgBox, 48, 提示, 请先选择【目标目录】
return
}
aDirName:=substr(A_LoopField,instr(A_LoopField,"\",,0,1)+1)
aItemName:=substr(A_LoopField,1,1) . "-" . aDirName
aUUID:=UUIDCreate()
GuiControlGet,aCompare,,Compare
GuiControlGet,aSynchronize,,Synchronize
aSourceDir:=A_LoopField
GuiControlGet,aDirectionDir,,DirectionDir
GuiControlGet,aErrorsIgnore,,ErrorsIgnore
GuiControlGet,aProgressDialogMinimized,,ProgressDialogMinimized
GuiControlGet,aProgressDialogAutoClose,,ProgressDialogAutoClose
GuiControlGet,aErrorDialog,,ErrorDialog
GuiControlGet,aPostSyncAction,,PostSyncAction
aDirectionDir:=aDirectionDir . "\" . aDirName
MsgBox, 36, 提示, 是否创建以下备份项目:`n--------------------------------------`n【项目名称】:%aItemName%`n【源文件夹】:%aSourceDir%`n【目标目录】:%aDirectionDir%
ifmsgbox,no
continue
if (aCompare="文件时间和大小")
aCompare:="TimeAndSize"
else if (aCompare="文件内容")
aCompare:="Content"
else if (aCompare="文件大小")
aCompare:="Size"
if (aSynchronize="双向 <->")
aSynchronize:="TwoWay"
else if (aSynchronize="镜像 ->")
aSynchronize:="Mirror"
else if (aSynchronize="更新 >")
aSynchronize:="Update"
if (aErrorDialog="取消备份")
aErrorDialog:="Cancel"
else
aErrorDialog:="Show"
if (aPostSyncAction="系统休眠")
aPostSyncAction:="Sleep"
else if (aPostSyncAction="系统关机")
aPostSyncAction:="Shutdown"
else
aPostSyncAction:="None"
aErrorsIgnore:=cBool(aErrorsIgnore)
aProgressDialogMinimized:=cBool(aProgressDialogMinimized)
aProgressDialogAutoClose:=cBool(aProgressDialogAutoClose)
aBackupItem:=new BackupItem(aUUID,aItemName,aCompare,aSynchronize,aSourceDir,aDirectionDir,aErrorsIgnore,aProgressDialogMinimized,aProgressDialogAutoClose,aErrorDialog,aPostSyncAction)
GuiControlGet,aProject_Sel,,Project_Sel
HasProject:=0
loop,% ProjectArray.length()
{
if (ProjectArray[A_index].Name=aProject_Sel){
ProjectArray[A_index].Items.push(aBackupItem)
HasProject:=1
break
}
}
if (!HasProject) {
Project:={}
Project.Items:={}
Project.Name:=aProject_Sel
Project.LastBuckupTime:=""
Project.Items.push(aBackupItem)
ProjectArray.push(Project)
}
Item_List.= "|" aItemName
GuiControl,,Item_Sel,|
GuiControl,,Item_Sel,%Item_List%
;~ GuiControl,ChooseString,Item_Sel,%aItemName%
;~ gosub,备份项目_变动
} else {
SplitPath,A_LoopField,,MyOutDir,MyOutExt,MyOutNameNoExt
If InStr("ffs_gui,ffs_batch", MyOutExt) { ;如果FreeFileSync文件
aBackupItem:=ReadXMLToBackupItem(A_LoopField)
aItemName:=MyOutNameNoExt
aBackupItem.ItemName:=aItemName
GuiControlGet,aProject_Sel,,Project_Sel
HasProject:=0
loop,% ProjectArray.length()
{
if (ProjectArray[A_index].Name=aProject_Sel){
ProjectArray[A_index].Items.push(aBackupItem)
HasProject:=1
break
}
}
if (!HasProject) {
Project:={}
Project.Items:={}
Project.Name:=aProject_Sel
Project.LastBuckupTime:=""
Project.Items.push(aBackupItem)
ProjectArray.push(Project)
}
Item_List.= "|" aItemName
GuiControl,,Item_Sel,|
GuiControl,,Item_Sel,%Item_List%
;~ GuiControl,ChooseString,Item_Sel,%aItemName%
;~ gosub,备份项目_变动
}
}
}
GuiControl,ChooseString,Item_Sel,%aItemName%
gosub,备份项目_变动
} else { ;单个文件
;判断是不是文件夹
If InStr(FileExist(MySel), "D") { ;区分是否文件夹,Attrib= D ,则是文件夹
if GetKeyState("Ctrl"){ ;检测是否按住Ctrl键
GuiControl,,DirectionDir,%MySel%
return
} else {
GuiControlGet,DirectionDir,,DirectionDir
if (DirectionDir=""){
MsgBox, 48, 提示, 请先选择【目标目录】
return
}
if RegExMatch(MySel,"i)[a-zA-Z]\:\\"){ ;如果是盘符
aDirName:=""
aItemName:=substr(MySel,1,1) . "-" . aDirName
} else {
aDirName:="\" . substr(MySel,instr(MySel,"\",,0,1)+1)
aItemName:=substr(MySel,1,1) . "-" . aDirName
}
GuiControl,,ItemName,%aItemName%
GuiControl,,SourceDir,%MySel%
GuiControlGet,DirectionDir,,DirectionDir
GuiControl,,DirectionDir,%DirectionDir%%aDirName%
GuiControlGet,Auto,,Auto
if Auto { ;如果自动批量
aUUID:=UUIDCreate()
GuiControlGet,aCompare,,Compare
GuiControlGet,aSynchronize,,Synchronize
GuiControlGet,aSourceDir,,SourceDir
GuiControlGet,aDirectionDir,,DirectionDir
GuiControlGet,aErrorsIgnore,,ErrorsIgnore
GuiControlGet,aProgressDialogMinimized,,ProgressDialogMinimized
GuiControlGet,aProgressDialogAutoClose,,ProgressDialogAutoClose
GuiControlGet,aErrorDialog,,ErrorDialog
GuiControlGet,aPostSyncAction,,PostSyncAction
if(aItemName="" or aSourceDir="" or aDirectionDir="") {
MsgBox, 0, 提示, 【项目名称】或【源文件夹】或【目标目录】为空,请重新输入
return
}
if (aCompare="文件时间和大小")
aCompare:="TimeAndSize"
else if (aCompare="文件内容")
aCompare:="Content"
else if (aCompare="文件大小")
aCompare:="Size"
if (aSynchronize="双向 <->")
aSynchronize:="TwoWay"
else if (aSynchronize="镜像 ->")
aSynchronize:="Mirror"
else if (aSynchronize="更新 >")
aSynchronize:="Update"
if (aErrorDialog="取消备份")
aErrorDialog:="Cancel"
else
aErrorDialog:="Show"
if (aPostSyncAction="系统休眠")
aPostSyncAction:="Sleep"
else if (aPostSyncAction="系统关机")
aPostSyncAction:="Shutdown"
else
aPostSyncAction:="None"
aErrorsIgnore:=cBool(aErrorsIgnore)
aProgressDialogMinimized:=cBool(aProgressDialogMinimized)
aProgressDialogAutoClose:=cBool(aProgressDialogAutoClose)
aBackupItem:=new BackupItem(aUUID,aItemName,aCompare,aSynchronize,aSourceDir,aDirectionDir,aErrorsIgnore,aProgressDialogMinimized,aProgressDialogAutoClose,aErrorDialog,aPostSyncAction)
GuiControlGet,aProject_Sel,,Project_Sel
HasProject:=0
loop,% ProjectArray.length()
{
if (ProjectArray[A_index].Name=aProject_Sel){
ProjectArray[A_index].Items.push(aBackupItem)
HasProject:=1
break
}
}
if (!HasProject) {
Project:={}
Project.Items:={}
Project.Name:=aProject_Sel
Project.LastBuckupTime:=""
Project.Items.push(aBackupItem)
ProjectArray.push(Project)
}
Item_List.= "|" aItemName
GuiControl,,Item_Sel,|
GuiControl,,Item_Sel,%Item_List%
GuiControl,ChooseString,Item_Sel,%aItemName%
gosub,备份项目_变动
}
}
} else {
SplitPath,MySel,,MyOutDir,MyOutExt,MyOutNameNoExt
If InStr("ffs_gui,ffs_batch", MyOutExt) { ;如果FreeFileSync文件
aBackupItem:=ReadXMLToBackupItem(MySel)
aItemName:=MyOutNameNoExt
aBackupItem.ItemName:=aItemName
GuiControlGet,aProject_Sel,,Project_Sel
HasProject:=0
loop,% ProjectArray.length()
{
if (ProjectArray[A_index].Name=aProject_Sel){
ProjectArray[A_index].Items.push(aBackupItem)
HasProject:=1
break
}
}
if (!HasProject) {
Project:={}
Project.Items:={}
Project.Name:=aProject_Sel
Project.LastBuckupTime:=""
Project.Items.push(aBackupItem)
ProjectArray.push(Project)
}
Item_List.= "|" aItemName
GuiControl,,Item_Sel,|
GuiControl,,Item_Sel,%Item_List%
GuiControl,ChooseString,Item_Sel,%aItemName%
gosub,备份项目_变动
}
}
;~ GuiControl,ChooseString,Item_Sel,%aItemName%
;~ gosub,备份项目_变动
}
return
;}
GuiContextMenu: ;{右键菜单-备份项目列表
if (A_GuiControl="Item_Sel") {
Menu,MyRightMenu,add
Menu,MyRightMenu,DeleteAll
Menu,MyRightMenu,add,执行选中备份,MenuHalder_Run
Menu,MyRightMenu,add
Menu,MyRightMenu,add,删除选中备份,MenuHalder_Del
Menu,MyRightMenu,add
Menu,MyRightMenu,add,比较选中文件夹,MenuHalder_Compare
menu,MyRightMenu,Show
}
return
;}
MenuHalder_Run: ;{右键菜单处理:执行选中备份
GuiControlGet,Project_Sel,,Project_Sel
GuiControlGet,Item_Sel,,Item_Sel
GuiControlGet,AppPath,,AppPath
if (AppPath=""){
MsgBox, 0, 提示, 请先指定FreeFileSync主程序目录
return
}
MsgBox, 36, 提示, 确认执行【%Item_Sel%】备份项目?
IfMsgBox,yes
{
BackupItemXML:=DeleteAllSpecialStringForFileName(Item_Sel)
FileRemoveDir, %A_Temp%\Kawvin_FFSBatch, 1
FileCreateDir, %A_Temp%\Kawvin_FFSBatch
BackupItemXML=%A_Temp%\Kawvin_FFSBatch\%BackupItemXML%.ffs_batch
WriteBackItemToXML(Project_Sel,Item_Sel,BackupItemXML)
runwait,"%AppPath%" "%BackupItemXML%"
FileRemoveDir, %A_Temp%\Kawvin_FFSBatch, 1
}
return
;}
MenuHalder_Del: ;{右键菜单处理:删除选中备份
GuiControlGet,Project_Sel,,Project_Sel
GuiControlGet,Item_Sel,,Item_Sel
MsgBox, 36, 提示, 确认删除【%Item_Sel%】备份项目?
IfMsgBox,yes
{
BreakMark:=0
loop,% ProjectArray.length()
{
aProject:=ProjectArray[A_index]
AIndex:=A_index
if (aProject.Name!=Project_Sel)
continue
aItem:=aProject.Items
loop,% aItem.Length()
{
if(aItem[A_index]["ItemName"]=Item_Sel) {
ProjectArray[AIndex].Items.removeat(A_index)
BreakMark:=1
break
}
}
if BreakMark
break
}
if regexmatch(Item_List, "(\|)" . Item_Sel . "(\|)")
Item_List:=RegExReplace(Item_List,"(\|)" . Item_Sel,"")
if regexmatch(Item_List, "^" . Item_Sel . "(\|)")
Item_List:=RegExReplace(Item_List,Item_Sel . "(\|)","")
if regexmatch(Item_List, "(\|)" . Item_Sel . "$")
Item_List:=RegExReplace(Item_List,"(\|)" . Item_Sel,"")
GuiControl,,Item_Sel,|
GuiControl,,Item_Sel,%Item_List%
Guicontrol,Choose,Item_Sel,1
gosub,备份项目_变动
}
return
;}
MenuHalder_Compare: ;{右键菜单处理:删除选中备份
BCAppPath=.\Beyond_Compare\BCompare.exe
IfNotExist,%BCAppPath%
{
MsgBox, 64, 提示, 【%BCAppPath%】软件不存在
return
}
GuiControlGet,Project_Sel,,Project_Sel
GuiControlGet,Item_Sel,,Item_Sel
global ProjectArray
BreakMark:=0
loop,% ProjectArray.length()
{
aProject:=ProjectArray[A_index]
if (aProject.Name!=Project_Sel)
continue
aItem:=aProject.Items
loop,% aItem.Length()
{
if(aItem[A_index]["ItemName"]=Item_Sel) {
BCompareLeftFile:=aItem[A_index]["SourceDir"]
BCompareRightFile:=aItem[A_index]["DirectionDir"]
BreakMark:=1
break
}
}
if BreakMark
break
}
;~ msgbox % BCompareLeftFile
;~ msgbox % BCompareRightFile
NotExit:=0
IfNotExist,%BCompareLeftFile%
NotExit:=1
IfNotExist,%BCompareRightFile%
NotExit:=1
if(NotExit=1){
MsgBox, 64, 提示, 源文件夹或目录文件夹不存在
return
}
Run,% BCAppPath " """ BCompareLeftFile """ """ BCompareRightFile """"
return
;}
一键备份: ;{
GuiControlGet,Project_Sel,,Project_Sel
GuiControlGet,AppPath,,AppPath
if (AppPath=""){
MsgBox, 0, 提示, 请先指定FreeFileSync主程序目录
return
}
MsgBox, 36, 提示, 确认执行【%Project_Sel%】备份计划下的所有备份项目?
IfMsgBox,yes
{
FileRemoveDir, %A_Temp%\Kawvin_FFSBatch, 1
FileCreateDir, %A_Temp%\Kawvin_FFSBatch
GuiControl,Show,Progress1
ItemCount:=0
Loop,parse,Item_List,|
{
if (A_LoopField="")
continue
ItemCount++
}
Loop,parse,Item_List,|
{
if (A_LoopField="")
continue
BackupItemXML:=DeleteAllSpecialStringForFileName(A_LoopField)
BackupItemXML=%A_Temp%\Kawvin_FFSBatch\%BackupItemXML%.ffs_batch
WriteBackItemToXML(Project_Sel,A_LoopField,BackupItemXML)
runwait,"%AppPath%" "%BackupItemXML%"
ProgressPercent:=a_index/ItemCount*100
GuiControl,,Progress1,%ProgressPercent%
}
FileRemoveDir, %A_Temp%\Kawvin_FFSBatch, 1
;写入最后备份时间
MyNowTime=%A_YYYY%.%A_MM%.%A_DD% %A_Hour%:%A_Min%:%A_Sec%
WriteLastBuckupTimeToXML(BackupXML,Project_Sel,MyNowTime)
GuiControl,,LastBackTime,最近备份:%MyNowTime%
;调整进度条
GuiControl,,Progress1,100
GuiControlget,ShutdownAfterfinish,,ShutdownAfterfinish
if (ShutdownAfterfinish=1)
MyFun_ShutDown(30)
else
msgbox ,备份完成
GuiControl,,Progress1,0
GuiControl,hide,Progress1
}
return
;}
备份计划_变动: ;{【2】备份计划-变动
GuiControlGet,Project_Sel,,Project_Sel
Item_List:=""
loop,% ProjectArray.length()
{
aProject:=ProjectArray[A_index]
if (aProject.Name!=Project_Sel)
continue
LastBackTime:=aProject.LastBuckupTime
aItem:=aProject.Items
loop,% aItem.Length()
{
Item_List:=Item_List . aItem[A_index]["ItemName"] . "|"
}
}
gosub,窗体初始化
GuiControl,,Item_Sel,|
GuiControl,,Item_Sel,%Item_List%
GuiControl,,LastBackTime,最近备份:%LastBackTime%
return
;}
备份项目_变动: ;{【2】备份项目-变动
GuiControlGet,Project_Sel,,Project_Sel
GuiControlGet,Item_Sel,,Item_Sel
gosub,窗体初始化
loop,% ProjectArray.length()
{
aProject:=ProjectArray[A_index]
if (aProject.Name!=Project_Sel)
continue
LastBackTime:=aProject.LastBuckupTime
aItem:=aProject.Items
loop,% aItem.Length()
{
if(aItem[A_index]["ItemName"]!=Item_Sel)
continue
GuiControl,,UUID,% aItem[A_index]["UUID"]
GuiControl,,ItemName,% aItem[A_index]["ItemName"]
if (aItem[A_index]["Compare"] ="TimeAndSize")
GuiControl,Choose,Compare,1
else if (aItem[A_index]["Compare"] ="Content")
GuiControl,Choose,Compare,2
else if (aItem[A_index]["Compare"] ="Size")
GuiControl,Choose,Compare,3
if (aItem[A_index]["Synchronize"] ="TwoWay")
GuiControl,Choose,Synchronize,1
else if (aItem[A_index]["Synchronize"] ="Mirror")
GuiControl,Choose,Synchronize,2
else if (aItem[A_index]["Synchronize"] ="Update")
GuiControl,Choose,Synchronize,3
GuiControl,,SourceDir,% aItem[A_index]["SourceDir"]
GuiControl,,DirectionDir,% aItem[A_index]["DirectionDir"]
if (aItem[A_index]["ErrorsIgnore"] ="true")
GuiControl,,ErrorsIgnore,1
else
GuiControl,,ErrorsIgnore,0
if (aItem[A_index]["ProgressDialogMinimized"] ="true")
GuiControl,,ProgressDialogMinimized,1
else
GuiControl,,ProgressDialogMinimized,0
if (aItem[A_index]["ProgressDialogAutoClose"] ="true")
GuiControl,,ProgressDialogAutoClose,1
else
GuiControl,,ProgressDialogAutoClose,0
if (aItem[A_index]["ErrorDialog"] ="Show")
GuiControl,Choose,ErrorDialog,1
else if (aItem[A_index]["ErrorDialog"] ="Cancel")
GuiControl,Choose,ErrorDialog,2
if (aItem[A_index]["PostSyncAction"] ="None")
GuiControl,Choose,PostSyncAction,1
else if (aItem[A_index]["PostSyncAction"] ="Sleep")
GuiControl,Choose,PostSyncAction,2
else if (aItem[A_index]["PostSyncAction"] ="Shutdown")
GuiControl,Choose,PostSyncAction,3
}
}
return
;}
窗体初始化: ;{全部窗体数据清空
GuiControl,,UUID,
GuiControl,,ItemName,
GuiControl,Choose,Compare,1
GuiControl,Choose,Synchronize,1
GuiControl,,SourceDir,
GuiControl,,DirectionDir,
GuiControl,,ErrorsIgnore,1
GuiControl,,ProgressDialogMinimized,0
GuiControl,,ProgressDialogAutoClose,1
GuiControl,Choose,ErrorDialog,1
GuiControl,Choose,PostSyncAction,1
;~ GuiControl,,Auto,1
return
;}
保存到XML: ;{
FileDelete,%BackupXML%
FileAppend,<?xml version="1.0" encoding="utf-8"?>`n,%BackupXML%,UTF-8
FileAppend,<Kawvin_BatchBackup>`n,%BackupXML%,UTF-8
FileAppend,`t<FreeFileSyncPath>%AppPath%</FreeFileSyncPath>`n,%BackupXML%,UTF-8
loop,% ProjectArray.length()
{
aProject:=ProjectArray[A_index]
AIndex:=A_index
aName:=aProject.Name
aLastBuckupTime:=aProject.LastBuckupTime
FileAppend,`t<BackupProject Name=`"%aName%`" LastBuckupTime=`"%aLastBuckupTime%`">`n,%BackupXML%,UTF-8
aItem:=aProject.Items
loop,% aItem.Length()
{
aUUID:=aItem[A_index]["UUID"]
FileAppend,`t`t<Item UUID=`"%aUUID%`">`n,%BackupXML%,UTF-8
aItemName:=aItem[A_index]["ItemName"]
FileAppend,`t`t`t<ItemName>%aItemName%</ItemName>`n,%BackupXML%,UTF-8
aCompare:=aItem[A_index]["Compare"]
FileAppend,`t`t`t<Compare>%aCompare%</Compare>`n,%BackupXML%,UTF-8
aSynchronize:=aItem[A_index]["Synchronize"]
FileAppend,`t`t`t<Synchronize>%aSynchronize%</Synchronize>`n,%BackupXML%,UTF-8
aSourceDir:=aItem[A_index]["SourceDir"]
FileAppend,`t`t`t<SourceDir>%aSourceDir%</SourceDir>`n,%BackupXML%,UTF-8
aDirectionDir:=aItem[A_index]["DirectionDir"]
FileAppend,`t`t`t<DirectionDir>%aDirectionDir%</DirectionDir>`n,%BackupXML%,UTF-8
aErrorsIgnore:=aItem[A_index]["ErrorsIgnore"]
FileAppend,`t`t`t<Errors Ignore=`"%aErrorsIgnore%`"/>`n,%BackupXML%,UTF-8
aProgressDialogMinimized:=aItem[A_index]["ProgressDialogMinimized"]
aProgressDialogAutoClose:=aItem[A_index]["ProgressDialogAutoClose"]
FileAppend,`t`t`t<ProgressDialog Minimized=`"%aProgressDialogMinimized%`" AutoClose=`"%aProgressDialogAutoClose%`"/>`n,%BackupXML%,UTF-8
aErrorDialog:=aItem[A_index]["ErrorDialog"]
FileAppend,`t`t`t<ErrorDialog>%aErrorDialog%</ErrorDialog>`n,%BackupXML%,UTF-8
aPostSyncAction:=aItem[A_index]["PostSyncAction"]
FileAppend,`t`t`t<PostSyncAction>%aPostSyncAction%</PostSyncAction>`n,%BackupXML%,UTF-8
FileAppend,`t`t</Item>`n,%BackupXML%,UTF-8
}
FileAppend,`t</BackupProject>`n,%BackupXML%,UTF-8
}
FileAppend,</Kawvin_BatchBackup>,%BackupXML%,UTF-8
MsgBox, 0, 提示, 保存到XML文件完成!
return
;}
确认修改: ;{
GuiControlGet,aUUID,,UUID
GuiControlGet,aProject_Sel,,Project_Sel
GuiControlGet,aItemName,,ItemName
GuiControlGet,aCompare,,Compare
GuiControlGet,aSynchronize,,Synchronize
GuiControlGet,aSourceDir,,SourceDir
GuiControlGet,aDirectionDir,,DirectionDir
GuiControlGet,aErrorsIgnore,,ErrorsIgnore
GuiControlGet,aProgressDialogMinimized,,ProgressDialogMinimized
GuiControlGet,aProgressDialogAutoClose,,ProgressDialogAutoClose
GuiControlGet,aErrorDialog,,ErrorDialog
GuiControlGet,aPostSyncAction,,PostSyncAction
if(aItemName="" or aSourceDir="" or aDirectionDir="") {
MsgBox, 0, 提示, 【项目名称】或【源文件夹】或【目标目录】为空,请重新输入
return
}
if (aCompare="文件时间和大小")
aCompare:="TimeAndSize"
else if (aCompare="文件内容")
aCompare:="Content"
else if (aCompare="文件大小")
aCompare:="Size"
if (aSynchronize="双向 <->")
aSynchronize:="TwoWay"
else if (aSynchronize="镜像 ->")
aSynchronize:="Mirror"
else if (aSynchronize="更新 >")
aSynchronize:="Update"
if (aErrorDialog="取消备份")
aErrorDialog:="Cancel"
else
aErrorDialog:="Show"
if (aPostSyncAction="系统休眠")
aPostSyncAction:="Sleep"
else if (aPostSyncAction="系统关机")
aPostSyncAction:="Shutdown"
else
aPostSyncAction:="None"
aErrorsIgnore:=cBool(aErrorsIgnore)
aProgressDialogMinimized:=cBool(aProgressDialogMinimized)
aProgressDialogAutoClose:=cBool(aProgressDialogAutoClose)
BreakMark:=0
loop,% ProjectArray.length()
{
aProject:=ProjectArray[A_index]
AIndex:=A_index
if (aProject.Name!=Project_Sel)
continue
aItem:=aProject.Items
loop,% aItem.Length()
{
if(aItem[A_index]["UUID"]=aUUID) {
ProjectArray[AIndex].Items[A_index]["ItemName"]:=aItemName
ProjectArray[AIndex].Items[A_index]["Compare"]:=aCompare
ProjectArray[AIndex].Items[A_index]["Synchronize"]:=aSynchronize
ProjectArray[AIndex].Items[A_index]["SourceDir"]:=aSourceDir
ProjectArray[AIndex].Items[A_index]["DirectionDir"]:=aDirectionDir
ProjectArray[AIndex].Items[A_index]["ErrorsIgnore"]:=aErrorsIgnore
ProjectArray[AIndex].Items[A_index]["ProgressDialogMinimized"]:=aProgressDialogMinimized
ProjectArray[AIndex].Items[A_index]["ProgressDialogAutoClose"]:=aProgressDialogAutoClose
ProjectArray[AIndex].Items[A_index]["ErrorDialog"]:=aErrorDialog
ProjectArray[AIndex].Items[A_index]["PostSyncAction"]:=aPostSyncAction
BreakMark:=1
break
}
}
if BreakMark
break
}
gosub,备份计划_变动
GuiControl,ChooseString,Item_Sel,%aItemName%
gosub,备份项目_变动
return
;}
ReadXMLToArray(BackupXML){ ;函数:读取XML文件到数组
global ProjectArray
global AppPath
global Project_List
ProjectArray:={}
xmlDoc := ComObjCreate("MSXML2.DOMDocument.6.0")
xmlDoc.async := false
xmlDoc.load(BackupXML)
AppPath:=xmlDoc.selectSingleNode("//FreeFileSyncPath") .text
ProjectNodes:=xmlDoc.selectNodes("//BackupProject")
for ProjectNode in ProjectNodes
{
Project:={}
Project.Items:={}
Project.Name:=ProjectNode.getAttribute("Name")
Project_List.= Project.Name "|"
Project.LastBuckupTime:=ProjectNode.getAttribute("LastBuckupTime")
ItemNodes:=ProjectNode.childNodes
for ItemNode in ItemNodes
{
aUUID:=ItemNode.getAttribute("UUID")
aItemName:=ItemNode.selectSingleNode("ItemName").text
aCompare:=ItemNode.selectSingleNode("Compare").text
aSynchronize:=ItemNode.selectSingleNode("Synchronize").text
aSourceDir:=ItemNode.selectSingleNode("SourceDir").text
aDirectionDir:=ItemNode.selectSingleNode("DirectionDir").text
aErrorsIgnore:=ItemNode.selectSingleNode("Errors").getAttribute("Ignore")
aProgressDialogMinimized:=ItemNode.selectSingleNode("ProgressDialog").getAttribute("Minimized")
aProgressDialogAutoClose:=ItemNode.selectSingleNode("ProgressDialog").getAttribute("AutoClose")
aErrorDialog:=ItemNode.selectSingleNode("ErrorDialog").text
aPostSyncAction:=ItemNode.selectSingleNode("PostSyncAction").text
aBackupItem:=new BackupItem(aUUID,aItemName,aCompare,aSynchronize,aSourceDir,aDirectionDir,aErrorsIgnore,aProgressDialogMinimized,aProgressDialogAutoClose,aErrorDialog,aPostSyncAction)
Project.Items.push(aBackupItem)
}
ProjectArray.push(Project)
}
}
ReadXMLToBackupItem(XMLFile){
xmlDoc := ComObjCreate("MSXML2.DOMDocument.6.0")
xmlDoc.async := false
xmlDoc.load(XMLFile)
aUUID:=UUIDCreate()
aItemName:=""
XmlFormat:=xmlDoc.selectSingleNode("/FreeFileSync").getAttribute("XmlFormat")
if (XmlFormat=12) {
aCompare:=xmlDoc.selectSingleNode("/FreeFileSync/Compare/Variant").text
aSynchronize:=xmlDoc.selectSingleNode("/FreeFileSync/Synchronize/Variant").text
aSourceDir:=xmlDoc.selectSingleNode("/FreeFileSync/FolderPairs/Pair/Left").text
aDirectionDir:=xmlDoc.selectSingleNode("/FreeFileSync/FolderPairs/Pair/Right").text
aErrorsIgnore:=xmlDoc.selectSingleNode("/FreeFileSync/Errors").getAttribute("Ignore")
try
aProgressDialogMinimized:=xmlDoc.selectSingleNode("/FreeFileSync/Batch/ProgressDialog").getAttribute("Minimized")
catch e
aProgressDialogMinimized:="false"
try
aProgressDialogAutoClose:=xmlDoc.selectSingleNode("/FreeFileSync/Batch/ProgressDialog").getAttribute("AutoClose")
catch e
aProgressDialogMinimized:="true"
try
aErrorDialog:=xmlDoc.selectSingleNode("/FreeFileSync/Batch/ErrorDialog").text
catch e
aProgressDialogMinimized:="show"
try
aPostSyncAction:=xmlDoc.selectSingleNode("/FreeFileSync/Batch/PostSyncAction").text
catch e
aProgressDialogMinimized:="none"
} else if (XmlFormat=11) {
} else if (XmlFormat=10) {
} else if (XmlFormat=9) {
} else if (XmlFormat=8) {
aCompare:=xmlDoc.selectSingleNode("/FreeFileSync/MainConfig/Comparison/Variant").text
aSynchronize:=xmlDoc.selectSingleNode("/FreeFileSync/MainConfig/SyncConfig/Variant").text
aSourceDir:=xmlDoc.selectSingleNode("/FreeFileSync/MainConfig/FolderPairs/Pair/Left").text
aDirectionDir:=xmlDoc.selectSingleNode("/FreeFileSync/MainConfig/FolderPairs/Pair/Right").text
aErrorsIgnore:=xmlDoc.selectSingleNode("/FreeFileSync/MainConfig/IgnoreErrors").text
try
aProgressDialogMinimized:=xmlDoc.selectSingleNode("/FreeFileSync/BatchConfig/RunMinimized").text
catch e
aProgressDialogMinimized:="false"
try
aProgressDialogAutoClose:=xmlDoc.selectSingleNode("/FreeFileSync/BatchConfig/ProgressDialog").getAttribute("AutoClose")
catch e
aProgressDialogMinimized:="true"
try
aErrorDialog:=xmlDoc.selectSingleNode("/FreeFileSync/BatchConfig/ErrorDialog").text
catch e
aProgressDialogMinimized:="show"
try
aPostSyncAction:=xmlDoc.selectSingleNode("/FreeFileSync/BatchConfig/PostSyncAction").text
catch e
aProgressDialogMinimized:="none"
} else if (XmlFormat=7) {
aCompare:=xmlDoc.selectSingleNode("/FreeFileSync/MainConfig/Comparison/Variant").text
aSynchronize:=xmlDoc.selectSingleNode("/FreeFileSync/MainConfig/SyncConfig/Variant").text
aSourceDir:=xmlDoc.selectSingleNode("/FreeFileSync/MainConfig/FolderPairs/Pair/Left").text
aDirectionDir:=xmlDoc.selectSingleNode("/FreeFileSync/MainConfig/FolderPairs/Pair/Right").text
aErrorsIgnore:=xmlDoc.selectSingleNode("/FreeFileSync/MainConfig/IgnoreErrors").text
try
aProgressDialogMinimized:=xmlDoc.selectSingleNode("/FreeFileSync/BatchConfig/RunMinimized").text
catch e
aProgressDialogMinimized:="false"
try
aProgressDialogAutoClose:=xmlDoc.selectSingleNode("/FreeFileSync/BatchConfig/ProgressDialog").getAttribute("AutoClose")
catch e
aProgressDialogMinimized:="true"
try
aErrorDialog:=xmlDoc.selectSingleNode("/FreeFileSync/BatchConfig/ErrorDialog").text
catch e
aProgressDialogMinimized:="show"
try
aPostSyncAction:=xmlDoc.selectSingleNode("/FreeFileSync/BatchConfig/PostSyncAction").text
catch e
aProgressDialogMinimized:="none"
} else if (XmlFormat=6) {
aCompare:=xmlDoc.selectSingleNode("/FreeFileSync/MainConfig/Comparison/Variant").text
aSynchronize:=xmlDoc.selectSingleNode("/FreeFileSync/MainConfig/SyncConfig/Variant").text
aSourceDir:=xmlDoc.selectSingleNode("/FreeFileSync/MainConfig/FolderPairs/Pair/Left").text
aDirectionDir:=xmlDoc.selectSingleNode("/FreeFileSync/MainConfig/FolderPairs/Pair/Right").text
aErrorsIgnore:=xmlDoc.selectSingleNode("/FreeFileSync/MainConfig/IgnoreErrors").text
try
aProgressDialogMinimized:=xmlDoc.selectSingleNode("/FreeFileSync/BatchConfig/RunMinimized").text
catch e
aProgressDialogMinimized:="false"
try
aProgressDialogAutoClose:=xmlDoc.selectSingleNode("/FreeFileSync/BatchConfig/ProgressDialog").getAttribute("AutoClose")
catch e
aProgressDialogMinimized:="true"
try
aErrorDialog:=xmlDoc.selectSingleNode("/FreeFileSync/BatchConfig/ErrorDialog").text
catch e
aProgressDialogMinimized:="show"
try
aPostSyncAction:=xmlDoc.selectSingleNode("/FreeFileSync/BatchConfig/PostSyncAction").text
catch e
aProgressDialogMinimized:="none"
} else {
}
aBackupItem:=new BackupItem(aUUID,aItemName,aCompare,aSynchronize,aSourceDir,aDirectionDir,aErrorsIgnore,aProgressDialogMinimized,aProgressDialogAutoClose,aErrorDialog,aPostSyncAction)
return aBackupItem
}
WriteLastBuckupTimeToXML(aXML,aProjectName,aLastBuckupTime){ ;写入内容到XML文件,参数aXML:文件名,aNode:节点,aType:类型(Text或属性),aValue:值
xmlDoc := ComObjCreate("MSXML2.DOMDocument.6.0")
xmlDoc.async := false
xmlDoc.load(aXML)
ProjectNodes:=xmlDoc.selectNodes("//BackupProject")
loop,% ProjectNodes.length()
{
aNode := ProjectNodes.item(A_Index-1)
if (aProjectName= aNode.getAttribute("Name"))
ProjectNodes.item(A_Index-1).setAttribute("LastBuckupTime", aLastBuckupTime)
break
}
xmlDoc.save(aXML)
}
WriteBackItemToXML(Project_Sel,aItemName,BackupItemXML){
global ProjectArray
BreakMark:=0
loop,% ProjectArray.length()
{
aProject:=ProjectArray[A_index]
if (aProject.Name!=Project_Sel)
continue
aItem:=aProject.Items
loop,% aItem.Length()
{
if(aItem[A_index]["ItemName"]=aItemName) {
;~ aItemName:=aItem[A_index]["ItemName"]
aCompare:=aItem[A_index]["Compare"]
aSynchronize:=aItem[A_index]["Synchronize"]
aSourceDir:=aItem[A_index]["SourceDir"]
aDirectionDir:=aItem[A_index]["DirectionDir"]
aErrorsIgnore:=aItem[A_index]["ErrorsIgnore"]
aProgressDialogMinimized:=aItem[A_index]["ProgressDialogMinimized"]
aProgressDialogAutoClose:=aItem[A_index]["ProgressDialogAutoClose"]
aErrorDialog:=aItem[A_index]["ErrorDialog"]
aPostSyncAction:=aItem[A_index]["PostSyncAction"]
FileAppend,<?xml version="1.0" encoding="utf-8"?>`n,%BackupItemXML%,UTF-8
FileAppend,<FreeFileSync XmlType="BATCH" XmlFormat="12">`n,%BackupItemXML%,UTF-8
FileAppend,`t<Compare>`n,%BackupItemXML%,UTF-8
FileAppend,`t`t<Variant>%aCompare%</Variant>`n,%BackupItemXML%,UTF-8
FileAppend,`t`t<Symlinks>Exclude</Symlinks>`n,%BackupItemXML%,UTF-8
FileAppend,`t`t<IgnoreTimeShift/>`n,%BackupItemXML%,UTF-8
FileAppend,`t</Compare>`n,%BackupItemXML%,UTF-8
FileAppend,`t<Synchronize>`n,%BackupItemXML%,UTF-8
FileAppend,`t`t<Variant>%aSynchronize%</Variant>`n,%BackupItemXML%,UTF-8
FileAppend,`t`t<DetectMovedFiles>false</DetectMovedFiles>`n,%BackupItemXML%,UTF-8
FileAppend,`t`t<DeletionPolicy>RecycleBin</DeletionPolicy>`n,%BackupItemXML%,UTF-8
FileAppend,`t`t<VersioningFolder Style="Replace"/>`n,%BackupItemXML%,UTF-8
FileAppend,`t</Synchronize>`n,%BackupItemXML%,UTF-8
FileAppend,`t<Filter>`n,%BackupItemXML%,UTF-8
FileAppend,`t`t<Include>`n,%BackupItemXML%,UTF-8
FileAppend,`t`t`t<Item>*</Item>`n,%BackupItemXML%,UTF-8
FileAppend,`t`t</Include>`n,%BackupItemXML%,UTF-8
FileAppend,`t`t<Exclude>`n,%BackupItemXML%,UTF-8
FileAppend,`t`t`t<Item>\System Volume Information\</Item>`n,%BackupItemXML%,UTF-8
FileAppend,`t`t`t<Item>\$Recycle.Bin\</Item>`n,%BackupItemXML%,UTF-8
FileAppend,`t`t`t<Item>\RECYCLER\</Item>`n,%BackupItemXML%,UTF-8
FileAppend,`t`t`t<Item>\RECYCLED\</Item>`n,%BackupItemXML%,UTF-8
FileAppend,`t`t`t<Item>*\desktop.ini</Item>`n,%BackupItemXML%,UTF-8
FileAppend,`t`t`t<Item>*\thumbs.db</Item>`n,%BackupItemXML%,UTF-8
FileAppend,`t`t</Exclude>`n,%BackupItemXML%,UTF-8
FileAppend,`t`t<TimeSpan Type="None">0</TimeSpan>`n,%BackupItemXML%,UTF-8
FileAppend,`t`t<SizeMin Unit="None">0</SizeMin>`n,%BackupItemXML%,UTF-8
FileAppend,`t`t<SizeMax Unit="None">0</SizeMax>`n,%BackupItemXML%,UTF-8
FileAppend,`t</Filter>`n,%BackupItemXML%,UTF-8
FileAppend,`t<FolderPairs>`n,%BackupItemXML%,UTF-8
FileAppend,`t`t<Pair>`n,%BackupItemXML%,UTF-8
FileAppend,`t`t`t<Left>%aSourceDir%</Left>`n,%BackupItemXML%,UTF-8
FileAppend,`t`t`t<Right>%aDirectionDir%</Right>`n,%BackupItemXML%,UTF-8
FileAppend,`t`t</Pair>`n,%BackupItemXML%,UTF-8
FileAppend,`t</FolderPairs>`n,%BackupItemXML%,UTF-8
FileAppend,`t<Errors Ignore=`"%aErrorsIgnore%`" Retry="0" Delay="5"/>`n,%BackupItemXML%,UTF-8
FileAppend,`t<PostSyncCommand Condition="Completion"/>`n,%BackupItemXML%,UTF-8
FileAppend,`t<Batch>`n,%BackupItemXML%,UTF-8
FileAppend,`t`t<ProgressDialog Minimized=`"%aProgressDialogMinimized%`" AutoClose=`"%aProgressDialogAutoClose%`"/>`n,%BackupItemXML%,UTF-8
FileAppend,`t`t<ErrorDialog>%aErrorDialog%</ErrorDialog>`n,%BackupItemXML%,UTF-8
FileAppend,`t`t<PostSyncAction>%aPostSyncAction%</PostSyncAction>`n,%BackupItemXML%,UTF-8
FileAppend,`t`t<LogfileFolder Limit="-1"/>`n,%BackupItemXML%,UTF-8
FileAppend,`t</Batch>`n,%BackupItemXML%,UTF-8
FileAppend,</FreeFileSync>,%BackupItemXML%,UTF-8
BreakMark:=1
break
}
}
if BreakMark
break
}
}
/* Class:BackupItem
类名:BackupItem
作用:根据条件,智能进行场景切换,并执行操作
作者: Kawvin
版本: 0.1
使用方法:aBackupItem:=new BackupItem(aUUID,aItemName,aCompare,aSynchronize,aSourceDir,aDirectionDir,aErrorsIgnore,aProgressDialogMinimized,aProgressDialogAutoClose,aErrorDialog,aPostSyncAction)
参数说明:
aUUID:UUID
aItemName:名称
aCompare :比较内容,TimeAndSize=文件时间及大小,Content=文件内容,Size=文件大小
aSynchronize:备份方式,TwoWay=双向,Update=更新,Mirror=镜像
aSourceDir:源文件夹
aDirectionDir:目标目录
aErrorsIgnore:是否忽略错误
aProgressDialogMinimized:最小化处理对话框
aProgressDialogAutoClose:自动关闭处理对话框
aErrorDialog:出错操作,Show=显示对话框,Cancel=取消备份
aPostSyncAction:运行完操作,sleep=系统休眠,Shutdown=系统关机
*/
class BackupItem{
;~ static ItemName:=""
;~ static Compare:=""
;~ static Synchronize:=""
;~ static SourceDir:=""
;~ static DirectionDir:=""
;~ static ErrorsIgnore:=""
;~ static ProgressDialogMinimized:=""
;~ static ProgressDialogAutoClose:=""
;~ static ErrorDialog:=""
;~ static PostSyncAction:=""
__New(aUUID,aItemName,aCompare:="TimeAndSize",aSynchronize:="TwoWay",aSourceDir:="",aDirectionDir:="",aErrorsIgnore:="true",aProgressDialogMinimized:="false",aProgressDialogAutoClose:="true",aErrorDialog:="",aPostSyncAction:="None"){
this.UUID:=aUUID
this.ItemName:=aItemName
this.Compare:=aCompare
this.Synchronize:=aSynchronize
this.SourceDir:=aSourceDir
this.DirectionDir:=aDirectionDir
this.ErrorsIgnore:=aErrorsIgnore
this.ProgressDialogMinimized:=aProgressDialogMinimized
this.ProgressDialogAutoClose:=aProgressDialogAutoClose
this.ErrorDialog:=aErrorDialog
this.PostSyncAction:=aPostSyncAction
}
}
UUIDCreate(mode:=1, format:="", ByRef UUID:=""){
UuidCreate := "Rpcrt4\UuidCreate"
if InStr("02", mode)
UuidCreate .= mode? "Sequential" : "Nil"
VarSetCapacity(UUID, 16, 0) ;// long(UInt) + 2*UShort + 8*UChar
if (DllCall(UuidCreate, "Ptr", &UUID) == 0)
&& (DllCall("Rpcrt4\UuidToString", "Ptr", &UUID, "UInt*", pString) == 0)
{
string := StrGet(pString)
DllCall("Rpcrt4\RpcStringFree", "UInt*", pString)
if InStr(format, "U")
DllCall("CharUpper", "Ptr", &string)
return InStr(format, "{") ? "{" . string . "}" : string
}
}
cBool(aNum){ ;将数字0或1转换为false或true
if (aNum=1)
return "true"
else
return "false"
}
MyFun_ShutDown(Sec){
global Timeout
SetTimer, ChangeStatic1Text, 1000
Timeout:=Sec
MsgBox, 4, 备份完成关机确认, 在【%Timeout%秒】内未点击【取消】,则自动关机, %Sec%
ifmsgbox,no
return
shutdown,5
}
ChangeStatic1Text: ;{
IfWinNotExist, 备份完成关机确认
return
WinActivate
Timeout-=1
ControlSetText, Static1, 在【%Timeout%秒】内未点击【取消】,则自动关机
return
;}
DeleteAllSpecialStringForFileName(aStr){ ;删除所有特殊的名称字符,\/*?:"<>|
bStr:=StrReplace(aStr,"\","")
bStr:=StrReplace(bStr,"/","")
bStr:=StrReplace(bStr,"*","")
bStr:=StrReplace(bStr,"?","")
bStr:=StrReplace(bStr,":","")
bStr:=StrReplace(bStr,"""","")
bStr:=StrReplace(bStr,"<","")
bStr:=StrReplace(bStr,">","")
bStr:=StrReplace(bStr,"|","")
return , bStr
}
Kawvin批处理备份(FreeFileSync)V6.1.5 的使用感受:
1、满意、好评,作者辛苦了,非常感谢作者的辛勤劳动和无私奉献。
2、免费、开源,可以永久使用,确实是个宝。
3、稳定高效简单易用,这个AutoHotkey脚本很稳定,很好用,FreeFileSync又是开源的 C++ 的源代码,很好很稳定。
4、此ahk脚本没有定时同步功能,没有自动同步功能,没有后台静默同步功能。
5、此ahk脚本没有连接群晖WebDAV功能,此ahk脚本没有连接群晖SFTP功能。
我建议作者参考借鉴GoodSync和SyncBackPro 的界面和功能做出相应改进和优化。
建议添加命令行参数传递功能和全局快捷键功能
建议添加后台定时自动静默备份指定的多个文件夹到多个目标位置的AutoHotkey脚本功能源代码片段
你这个做出来,就成了后台的实时备份系统了,和我原来的初衷有所不同,不过也是可以实现的,就是整个逻辑要修改一下了。
高级啊,希望我有朝一日也能达到这么高的水平!!!