中国DOS联盟论坛

中国DOS联盟

-- 联合DOS 推动DOS 发展DOS --
联盟域名:www.cn-dos.net 论坛域名:www.cn-dos.net/forum
游客 | 登录 | 注册 | 会员 | 搜索 | 中国DOS联盟
中国DOS联盟论坛
现在时间是 2026-08-25 23:49
47,812 主题排行 / 349,910 发帖 / 今日 0 篇 / 48,264 会员排行
DOS批处理 & 脚本技术(批处理室) » [原创][XP]文件备份器V2.4(Final) [07-4-8更新]
可打印版本  35,973 / 112
第1楼 namejm 发表于 2006-05-22 23:35
荣誉版主 发帖 1,737 积分 5,226 来自 成都
[原创][XP]文件备份器V2.4(Final) [07-4-8更新]
  当前讨论:

  本人机子为XP系统,要备份的文件为"c:\program files\家易理财 2004\date"文件夹下的文件,该文件夹下只有几个.mdf格式(该软件自带格式)的数据文件,保存到"E:\家易理财数据备份"文件夹下,备份的时间为每天的12:00 19:00 22:00。今天21点的时候打开电脑,提示说备份服务不正常,22点之前改动了date文件夹下的文件,22点之后查看"E:\家易理财数据备份"下的日志,发现没有备份记录,再查看该文件夹下的文件,没有任何改动,打开任务管理器查看进程,cmd.exe和xcopy.exe一直在运行,在C:\WINDOWS\Tasks下查看状态,At1空白(12:40的时候已经执行了备份动作),At2为"错过",At3为"正在运行",请问这是什么原因?

  这个问题已经解决,解决办法见6楼的描述。

  经过N次修改的备份程序完整代码如下。

  已知的问题:

1、CMD复制某些文件时会出错,会导致文件不能完整地备份,原因正在查找中,不过几率相当低;

  2、暂无,期待大家更多的测试反馈




  更新历史:


  注:
  1.因为还没找到显示比例为4:3的电脑显示器,只能将就我的显示比例了(分辨率为1280×768);
  2.自动完成文件名这一功能非常实用,但尚有不完善之处,详情请看46楼,请各位高手帮忙解决;
  3.当xcopy加上/e参数时,复制文件的时候会把文件所在目录下的文件夹(不包含其中的文件)都复制过去;当备份的是文件夹且结构为"文件夹1-文件夹2-文件夹3-文件"的时候,会去掉最上层的文件夹;百思不得其解;
  4.更新之处请看更新历史;
5.有没有谁装了2K的系统,如果有的话,请帮忙测试一下在2K下能不能通过(要把:check_system这一节代码去掉),有测试过的请帮忙回帖反馈一下。目前我只知道在显示%date%和%time%的时候会不一样;
  6.如果有什么地方需要完善的,欢迎跟帖;

  有关本程序的讨论主要有:

什么情况下该使用变量延迟?
http://www.cn-dos.net/forum/viewthread.php?tid=20733

监视文件操作的批处理该如何编写?
http://www.cn-dos.net/forum/viewthread.php?tid=20732

如何用固定长度显示长度不一致的字符?
http://www.cn-dos.net/forum/viewthread.php?tid=20734

怎样去掉DOS窗口的下拉条
http://www.cn-dos.net/forum/viewthread.php?tid=20040

at命令中为什么无法显示%username%
http://www.cn-dos.net/forum/viewthread.php?tid=20238

如何显示磁盘的剩余空间?
http://www.cn-dos.net/forum/viewthread.php?tid=19738

长文件名如何应用于批处理文件中
http://www.cn-dos.net/forum/viewthread.php?tid=19223

在2K环境下date命令的运行结果
http://www.cn-dos.net/forum/viewthread.php?tid=20043

如何检测文件名带空格的文件夹是否存在
http://www.cn-dos.net/forum/viewthread.php?tid=19836

怎样复制指定内容到指定文件里去
http://www.cn-dos.net/forum/viewthread.php?tid=19855

dir命令查询目录找不到文件是什么原因
http://www.cn-dos.net/forum/viewthread.php?tid=19803

[ Last edited by namejm on 2007-4-8 at 11:18 AM ]

附件
文件备份器(Final).rar (117.32 KiB)
第2楼 willsort 发表于 2006-05-23 01:47
元老会员 发帖 1,512 积分 4,432
Re namejm:

很不错的一个批处理脚本,可以看出兄十分用心。因此我有一个建议,将此主题改造为关于“文件自动备份批处理脚本”的原创主题,首帖转贴最新的源码,回复帖对其中涉及的若干细节和问题进行讨论。这要求转移和合并你过去发表的一些主题帖,因此需要征得你的同意。

关于at3命令的执行问题,因为代码尚没有看完,因此无法发表什么意见,仅推测似与其所对应的备份脚本有关,因此需要贴出这段批处理的代码。

另外,仅就以下引用自源码中的一节略作讨论:


set /p source= 请输入要备份文件的路径:
:: 这里可以提示直接将备份目标拖拽入运行窗口中,即可获得源路径

for /f "delims=:\" %%i in ("%source%") do set subarea1=%%i
:: 似乎是获取源的盘符,为何不使用 set subarea1=%source:~0,1%

if not "%source%"=="" set source=%source%
:: 此句意义未明,尚请指教
:: 如果是将路径格式化,需要使用for %%p in ("%source%") do set source=%%~fp

if "%source%"=="" goto input_source
:: 建议将直接按下回车的选择(即%source%为空)分配给使用频率高的操作
if "%source%"=="0" exit
if "%source%"=="1" goto backup_task

echo "%source%"|find "%subarea1%:\" > nul
if "%ERRORLEVEL%"=="1" goto input_source
:: 判断路径中是否含有盘符?可否用 if "%source:~1,2%"==":\"

if "%source%"=="%subarea1%:\" goto forbid
:: 判断路径是否为根路径?当 source 为 C:\\ 或者 C:\. 时将不起作用

if not exist "%source%" goto source_noexist
goto input_object
:: object 的含义为对象,与备份目标有歧义,不如改为target或destination


[ Last edited by willsort on 2006-5-23 at 01:48 ]
第3楼 bagpipe 发表于 2006-05-23 12:30
银牌会员 发帖 425 积分 1,144 来自 北京
LZ真是有耐心,这么长,比我毕业论文都长,佩服,佩服..........正如WILLSOFT所说代码没有看完呢还得慢慢消化一下才可以的............
第4楼 Climbing 发表于 2006-05-23 13:05
铂金会员 发帖 2,753 积分 6,962 来自 河北保定
我觉得at出现的错误跟批处理没有太大的关系,有可能是有其它方面的原因。

从楼主的批处理来看,只要有一个at计划正常运行了,那么其它的也应该没有问题。

对楼主的耐心表示敬意,不过,如果你仅仅是为了实现文件备份功能而写这个批处理,实在不如引进一些第三方工具来得简单,例如:SecondCopy,或者同步软件CmdSync等 。当然,个人的环境不同,所以方法也不同,我的仅仅是建议。
第5楼 doscc 发表于 2006-05-23 14:11
中级用户 发帖 93 积分 256 来自 广东
同意4楼的建议!

对楼主的耐心表示敬意

虽然脚本可以帮我们完成一些 大量重复的工作!
但是有时用一些第三方软件也不错的.
第6楼 namejm 发表于 2006-05-23 14:18
荣誉版主 发帖 1,737 积分 5,226 来自 成都
to willsort 版主:
我不清楚你进行"转移和合并你过去发表的一些主题帖"这个操作的时候需要什么条件,我十分高兴这个脚本能得到大家的进一步完善,请版主按照你的想法编辑就是了,有什么地方需要我做的,我尽量配合.谢谢willsort.
报告一下问题所在:
刚才突然回想起手动执行生成的计划任务批处理,屏幕显示"……是否改写?(YES or NO or All)"(大意如此,现在时间匆忙,没来得及细看),看来是因为at是后台运行的,对需要手动确认的命令不会作任何提示,所以造成了cmd.exe和xcopy.exe进程一直存在,而备份操作没有执行的现象.
现在在xcopy一句后加上 /y 参数,问题解决.
各位的回复都看了一下,看来这个脚本还有很多需要完善的细节.因为马上要上班去了,没时间一一回复,只有等下了班再来回答,请各位原谅.同时,也请大家继续挑里面的毛病,特别是看有有些地方没有什么更好的解决办法.在此谢过各位.
第7楼 namejm 发表于 2006-05-23 18:40
荣誉版主 发帖 1,737 积分 5,226 来自 成都
感谢willsort版主的点评,以下是我的一些想法:
"set /p source= 请输入要备份文件的路径:
:: 这里可以提示直接将备份目标拖拽入运行窗口中,即可获得源路径"
——居然还可以直接拖过去就能显示路径,呵呵,意外收获,在此谢过willsort。如果路径带有空格,直接拖过去的话,会自动在路径首尾添加引号,而当初为了照顾手工输入带空格的路径,下面的变量引用都是加了引号的,如果提示用拖曳的办法的话,会造成程序出错。如果不允许手工输入只允许拖曳的话,再去掉变量引用的引号,应该可以解决这个矛盾。暂时还不好取舍。

"for /f "delims=:\" %%i in ("%source%") do set subarea1=%%i
:: 似乎是获取源的盘符,为何不使用 set subarea1=%source:~0,1%"
——如果用拖曳的方法输入的路径带空格的话,只能取到前引号。如果采用上一条的方案,只允许拖曳的话,会导致错误,看来拖曳的方法挺容易出错的。

"if not "%source%"=="" set source=%source%
:: 此句意义未明,尚请指教
:: 如果是将路径格式化,需要使用for %%p in ("%source%") do set source=%%~fp"
——说实话,这句我也不太弄得明白,是我从深山红叶光盘的批处理程序中抄袭过来的,当时以为是获取键盘输入的一种格式,没有细想。

"if "%source%"=="" goto input_source
:: 建议将直接按下回车的选择(即%source%为空)分配给使用频率高的操作
if "%source%"=="0" exit
if "%source%"=="1" goto backup_task"
——我的本意是检测是否有输入内容,如果没有的话,则强制输入,不允许跳过,感觉这样处理比较好,暂时不打算更改此处代码。

"echo "%source%"|find "%subarea1%:\" > nul
if "%ERRORLEVEL%"=="1" goto input_source
:: 判断路径中是否含有盘符?可否用 if "%source:~1,2%"==":\" "
——同上面的道理,在拖曳输入的时候,只能取到前引号。


"if "%source%"=="%subarea1%:\" goto forbid
:: 判断路径是否为根路径?当 source 为 C:\\ 或者 C:\. 时将不起作用"
——当时没有考虑到这种情况,多谢版主提醒,现在在后面增加两行代码,应该可以避免这个错误:
if "%source%"=="%subarea1%:\\" goto forbid
if "%source%"=="%subarea1%:\." goto forbid

"if not exist "%source%" goto source_noexist
goto input_object
:: object 的含义为对象,与备份目标有歧义,不如改为target或destination"
——说起来惭愧,对E文我一向比较头疼,所以经常会闹笑话。在新的代码里已经改过来了。多谢指正。

以下是修改过的代码:

[ Last edited by willsort on 2006-5-24 at 01:42 ]
第8楼 namejm 发表于 2006-05-23 18:54
荣誉版主 发帖 1,737 积分 5,226 来自 成都
Originally posted by Climbing at 2006-5-23 13:05:
对楼主的耐心表示敬意,不过,如果你仅仅是为了实现文件备份功能而写这个批处理,实在不如引进一些第三方工具来得简单,例如:SecondCopy,或者同步软件CmdSync等 。当然,个人的环境不同,所以方法也不同,我的仅仅是建议。

多谢老兄提供了这两个程序的线索,网上搜索了一下,它们的功能令人怦然心动。
但是有两个缺陷:1.正如我在这个脚本程序的更新历史里所说的那样,“网上的备份软件有诸多限制”,SecondCopy有30天免费使用期的限制,像我等不会破解之道的菜鸟,拿来使用30天之后,可能又得把系统时间往前调N天(还不一定有效),或者再手工备份,而网上的注册码都是过了期的,破解的似乎也没有;2.都是E文的。这个一直是令我很头疼的事情。虽然知道不多懂点E文在网络里不好混,在现实生活中也混不好,但是自己专业的限制,大学毕业之后就没多少心思再在E文上下工夫,所以我用的软件要么是国人开发的,要么就是汉化过的,可怜:(
综合以上原因,我决定还是自己编一个脚本程序,一来可以练技术,二来也可以拿来给我那些比我更菜的朋友们用。苦笑ing……
第9楼 willsort 发表于 2006-05-24 02:47
元老会员 发帖 1,512 积分 4,432
Re namejm:

我已经将主题首帖作了一些改动,包括标题的修改和正文内容顺序的调整。

原来试图将所有兄所发的与本程序有关的讨论主题合并到这里来,却发现兄对这个脚本下了不少功夫,竟然发现了十数个主题与此相关,如此一来,合并工作量大不说,也会导致许多原来相关性不大的讨论主题夹杂在同一主题中,反而降低了主题的作用。因此,最终决定只在首帖中给出所有相关讨论主题的链接以供查阅索引。

其次,将兄7楼中的代码转移到首帖中,这是考虑到以下原因:一是因为代码体积过大,如果出现多个差异不大的版本,将会降低页面的打开速度、增加用户的阅读时间,同时耗费更多的论坛空间和时间资源;二是因为我们发表程序的原则是尽可能让用户以最方便的方式获取最新的版本,而如果将新版本更新在回复帖中,可能需要滚动甚至翻页才能得到,那就抬高了推广的门槛。因此,建议兄发布新版程序时,也能将代码编辑到首帖中。

再次,关于我引用的那一小节,你的两难是可以解决的。用户可以拖拽备份源,也可以直接输入源路径(绝对路径或者相对路径),无论它是否含有引号,无论它是否含有非标准的路径引用方式(C:\\,C:\.\),我们都可以通过对路径串进行预先的格式标准化处理来解决这些不兼容的问题。以下的语句可以剔除路径中可能存在的引号,将相对路径转换为绝对路径,将非标准路径转换为标准路径(C:\\-->C:\),并判断路径是否有效地存在,是否是根路径。 不过它仍无法抵抗路径中出现的非法字符(>|),不知其他兄弟还有什么更好的办法没有?

最后,不知兄使用何种环境编写代码?但从注释的宽度达到114来看,兄或许使用的是宽屏显示器,所以不虞注释的换行浏览问题。然而根据论坛和我的系统环境(17"+XP+EditPlus2)中贴出的代码来看,无论是否开启自动换行功能,注释的宽度过大都影响了代码的可阅读性。



[ Last edited by willsort on 2006-5-24 at 02:54 ]
第10楼 namejm 发表于 2006-05-24 12:48
荣誉版主 发帖 1,737 积分 5,226 来自 成都
Originally posted by willsort at 2006-5-24 02:47:
Re namejm:

最后,不知兄使用何种环境编写代码?但从注释的宽度达到114来看,兄或许使用的是宽屏显示器,所以不虞注释的换行浏览问题。然而根据论坛和我的系统环境(17"+XP+EditPlus2)中贴出的代码来看,无论是否开启自动换行功能,注释的宽度过大都影响了代码的可阅读性。


老大果然一眼看出问题的所在,我用的正是宽屏电脑,14''+XP,分辨率为1280×768,以前在学做网页的时候就因为宽屏的原因与标准的4:3屏幕不一致而痛苦不堪,现在居然把这个细节给搞忘记了,真是一语惊醒梦中人,看来得找个4:3的显示器来修改.
最初不是为了编这个脚本才发的帖子,而是因为在做光盘的时候,要从光盘中提取指定的E书到电脑上.随着兴趣的越发浓厚,而对批处理的热情一发不可收拾,在自己的电脑上捣鼓了不少脚本来增强系统的功能,自我娱乐.刚下班回来,还有点头昏脑胀,先睡个午觉,晚上下班回来再回复,请各位原谅.
第11楼 namejm 发表于 2006-05-24 17:32
荣誉版主 发帖 1,737 积分 5,226 来自 成都
Originally posted by willsort at 2006-5-24 02:47:
Re namejm:

再次,关于我引用的那一小节,你的两难是可以解决的。用户可以拖拽备份源,也可以直接输入源路径(绝对路径或者相对路径),无论它是否含有引号,无论它是否含有非标准的路径引用方式(C:\\,C:\.\),我们都可以通过对路径串进行预先的格式标准化处理来解决这些不兼容的问题。以下的语句可以剔除路径中可能存在的引号,将相对路径转换为绝对路径,将非标准路径转换为标准路径(C:\\-->C:\),并判断路径是否有效地存在,是否是根路径。 不过它仍无法抵抗路径中出现的非法字符(>|),不知其他兄弟还有什么更好的办法没有?


能不能把路径用for来解析,如果有非法符号就跳转到警告界面?
第12楼 namejm 发表于 2006-05-24 23:54
荣誉版主 发帖 1,737 积分 5,226 来自 成都
Originally posted by willsort at 2006-5-24 02:47:
Re namejm:

set _src=
for %%p in ("%source%") do if exist %%p set _src=%%~fp
if "%_src%"=="" for %%p in (%source%) do if exist %%p set _src=%%~fp
if "%_src:~1,2%"==":\" goto forbid
set source=%_src%


把上面这段代码压缩成一句插入,测试了一下,觉得没什么问题,已经更新到脚本里去了,更新位置如下:


发现个问题,看来还得改动输入提示


第13楼 willsort 发表于 2006-05-25 00:12
元老会员 发帖 1,512 积分 4,432
Re namejm:

问题的关键在于我们不能确定路径串的前后是否存在引号,所以不能贸然决定是否使用引号包含路径串,所以无法约束其中的非法字符。这我曾在中作过类似的讨论,目前没有很好的解决办法。

而任何对路径串进行探测和分析的语句(无论echoif、for),都要求命令行中出现路径串本身,而如果未受约束的非法字符显然会破坏命令行的正常秩序。甚至可能不会出现语法错误的提示,而意外地产生一些垃圾文件。

在你现在的代码中,如果某些用户为了安全起见而将含空格路径用引号引起,那么代码显然会语法错误而中止。而目前为止,我们测试的仍只是善意用户的合法行为,还没有真正进行一些非善意的极限边界测试。

所以说,要编制一个“健壮性”很强的代码是很困难的,尤其是在自由灵活的批处理中。

批处理编程的异类: if语句中防空字符的选择
http://www.cn-dos.net/forum/viewthread.php?tid=12388#pid100419
第14楼 namejm 发表于 2006-05-25 18:32
荣誉版主 发帖 1,737 积分 5,226 来自 成都
Originally posted by willsort at 2006-5-24 02:47:
Re namejm:
以下的语句可以剔除路径中可能存在的引号,将相对路径转换为绝对路径,将非标准路径转换为标准路径(C:\\-->C:\),并判断路径是否有效地存在,是否是根路径。



以上的代码我插入到
set source=
set /p source= 请输入要备份文件的路径:


if not "%source%"=="" set source=%source%
if "%source%"=="" goto input_source
if "%source%"=="0" exit
if "%source%"=="1" goto backup_task

之间,并不能剔除带空格路径中的前后引号,而是跳转到禁止全盘复制的界面,难道是我插入的位置错了吗?

[ Last edited by namejm on 2006-5-25 at 22:38 ]
第15楼 willsort 发表于 2006-05-25 22:30
元老会员 发帖 1,512 积分 4,432
Re namejm:

很抱歉!问题出在if "%_src:~1,2%"==":\" goto forbid句上,这句代码是我在完成路径测试后,转贴前临时插入进去的,因未经测试而导致出错!将它改为if "%_src:~1,3%"==":\" goto forbid可以解决问题。

但以上代码还无法完善解决不存在文件及文件夹路径串的问题,将代码替换为代码可以解决这个问题。当然,新代码仍然无法防御“<|>”这些非法字符。

Old code


New code
1 2 3 48  下一页
[ 联系联盟系统管理团队 - 中国DOS联盟 - 标准版 ]
Sponsored by ifanr Inc | © 2001–2023