![]() |
中国DOS联盟-- 联合DOS 推动DOS 发展DOS --联盟域名:www.cn-dos.net 论坛域名:www.cn-dos.net/forum |
| 游客 | 登录 | 注册 | 会员 | 搜索 | 中国DOS联盟 |
|
中国DOS联盟论坛 现在时间是 2026-08-03 14:12 |
共 48,038 主题排行 / 350,123 发帖 / 今日 0 篇 / 48,251 会员排行 |
| DOS批处理 & 脚本技术(批处理室) » 【共同参与】"批处理函数库" |
| 可打印版本 10,299 / 36 |
| 第1楼 plp626 | 发表于 2008-04-01 23:17 |
| 银牌会员 发帖 1,020 积分 2,278 | |
|
【共同参与】"批处理函数库" 为了防止某些人灌水设了积分限制,请谅解,,
学了几个月批处理感觉收获真不少,(主要是好玩) 只是感觉功夫长进没有原来那么明显了,大部分时间都是在编一些重复的代码,即使一个很有挑战行动代码,花了不少功夫编出来,回过头认真一搜,论坛以前就有类似的代码,只是需要把各种方法"整合"就可以完成自己的代码了, 借鉴别人的,然后改进综合,这样进步才会很快. 只是很少人做这个工作,起码willsort以前发的帖子注意的人就寥寥(个人认为, 只有足够的函数,才能往面向对象那里想) 大家把自己能知道的一些常用的函数,(基本是都是call调用)共享下,交流下,然后极少成多多了,以后编代码就光查,既省时有省力, (对于"私藏者",我引用一个小朋友的话"别当那是个宝,说不定还是个...,大家交流下说不定还有更高效的算法,这对你总是有好处的). 感觉很好的子过程或函数请发到这个帖子: http://www.cn-dos.net/forum/viewthread.php?tid=39777&fpage=1常用子过程、函数收集【专用帖】 我这里有篇文章,虽然是英文但说的很到位,就是告诉我们些批处理函数的标准格式,供他人方便调用. 函数也就分有参函数与无参函数: 无参函数 有参函数: 对于注释部分以及变量的定义与返回,需要个规范,大家参考下面文章,交流下, 我英文不好,就不翻译,英语差点自己到http://www.google.cn/language_tools搜. [ Last edited by plp626 on 2008-4-27 at 12:12 AM ] |
|
| 第2楼 plp626 | 发表于 2008-04-01 23:35 |
| 银牌会员 发帖 1,020 积分 2,278 | |
|
Batch Function Library 原文:http://commandline.co.uk/lib/treeview/index.php ●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●● Batch Function Overview (批处理函数概述) What are they? A batch function is a block of batch code that can be called by a batch file, optionally with a number of parameters. The function performs its task without unintentionally modifying variables outside of its own scope, and then returns control to the statement following the one that called the function. Why use them? The primary benefit of functions is reusable code. Once a function has been written, it can be used over and over again. This reduces the time spent developing and debugging scripts Scripts that use functions naturally have a modular structure and use fewer 'global' variables, therefore they are much easier to understand, debug and maintain. What do they look like? All the functions in the library are based on the following template(下面是提供的模板): ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: :<Function Name> <Parameter list> :: :: By: <Author/date/version information> :: :: Func: <Function description> :: :: Args: <Argument description> ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: setlocal ENABLEEXTENSIONS <Body of function> endlocal&<Set return values>&goto :EOF ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: <Function name> Name of the function, eg GetDate <Parameter list> List of arguments. This list only serves as a reminder of how to call the function (everything after the function name is ignored by the command interpreter) <Author/date/version information> Self explanatory <Function description> Brief explanation of what the function does and which platforms it has been designed for (NT4, W2K or XP) <Argument description> Detailed description of the functions arguments <Body of function> This is where the function performs its main purpose <Set return values> This is where the function 'returns' any local values back to the calling routine ●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●● Batch Functions Explained (批处理函数解释) Passing Arguments Most high-level programming languages allow arguments to be passed to functions 'by value' and 'by reference'. Passing by value means that the function receives a copy of the arguments value. Any changes made to this copy by the function do no affect the original variable. When a variable is passed by reference, the function receives a pointer to the original variable, and loosely speaking, changes made to this pointer by the function do affect the original variable. In the batch programming language variables are passed by reference. Unfortunately the pointers to the original variables are read only and consequently cannot be assigned values and therefore are unable to alter the variable which they point to. The good news is that with a little ingenuity, the batch language can be coerced into passing variables by value and by reference in a similar way to high-level languages such as C and Visual Basic. By Value Below is a very simple example showing how to pass an argument by value and how that value is then read by the function. 1. @echo off & setlocal ENABLEEXTENSIONS 2. set str=Hello 3. call :demoA %str% 4. goto :EOF 5. 6. :demoA 7. echo/%1 8. goto :EOF In line 3, %str% is expanded to Hello, and then the memory location of where Hello is actually stored is assigned to %1. Line 7 then references %1 which is then expanded to Hello. If two or more arguments were being passed, they could be referenced using %2, %3 and so on, all the way up to %9. If more than nine variables were being passed, then to reference the tenth, the shift command would have to be used. shift effectively increments all the pointers. Before shift is used, %0 points to the name of the function or routine and %1 points to the first argument. After shift is used, %0 points to what %1 used to point to, %1 points to what %2 used to point to and so on. The tenth argument can now be referenced using %9. By Reference Here is a slighty different version of the example above. Instead of passing the value Hello to the function, the name of a variable that contains Hello is passed instead. 1. @echo off & setlocal ENABLEEXTENSIONS 2. set str=Hello 3. call :demoB str 4. goto :EOF 5. 6. :demoB 7. call echo/%%%1%% 8. goto :EOF Inside the function demoB, %1 expands to str. To read the value contained in str, it is necessary to enclose %1 with double percents and instruct the command interpreter to perform another expansion. This is most easily accomplished by using the CALL command as shown in line 7. For a detailed explanation of variable expansion, see the thread in alt.msdos.batch.nt titled "Variable expansion (W2KSP2)". Why would we want to pass arguments like this? Well now that the function knows the name of a variable, it can assign it a value and thereby the function can now return values. Returning Values So far the contrived examples have only served to illustrate the points being made. This next example demonstrates how a function can return a value and is typical of the functions in this library. The methods used guarantee this function can be inserted, as it stands, into any batch file without causing any side effects whatsoever. The function below is called Area and it simply calculates the product of width and height and then returns the result. Three arguments are required, the first two should be passed by value, the third by reference. 01. @echo off & setlocal ENABLEEXTENSIONS 02. set x=2 03. set y=3 04. call :Area %x% %y% answer 05. echo/The area is: %answer% 06. goto :EOF 07. 08. :Area %width% %height% result 09. setlocal 10. set /a res=%1*%2 11. endlocal & set "%3=%res%" 12. goto :EOF Line 04 calls the Area function passing three arguments (it could equally have read call :Area 2 3 answer). The first command of the function (line 09) is setlocal. This command creates a copy of the current environment and this copy then becomes the current environment. Line 10 calculates the product of arguments %1 and %2 and saves the result in the variable called res. The next line consists of two commands seperated by an ampersand (&). This causes the command interpreter to expand both commands and then execute them one after the other. So line 11, after it has been expanded equates to endlocal & set "answer=6". Now the endlocal command is executed, which deletes the copy of the environment created by the most recent setlocal command, and restores the previous environent. Then set "answer=6" is executed, and finally on line 12 goto :EOF exits the function and execution continues at line 05. The net result is that the Area function has returned a value. If on line 11, the command set "%3=%res%", had been expanded after endlocal had been executed, then instead of expanding to set "answer=6" it probably would have been set "answer=" as the res variable was deleted by the endlocal command. By Value or Reference The rule of thumb is to pass arguments by value unless you need to modify the original values, in which case pass by reference. The Area function above demonstrates this rule as the first and second arguments (width and height) are passed by value, but in order to assign the result of the calculation to the answer variable, it was passed to the function by reference. Sometimes it's necessary to pass arguments by reference even though read-only access is required. For example, when passing two or more unquoted arguments where at least one of them contains whitespace, the function would not be able to determine which argument was which if they had been passed by value. Calling by reference can also be used to pass arguments containing so-called 'poison' characters (such as " ! | < > ^ " & %). Protecting out of Scope Variables In order to create truely reusable functions, you must ensure that they do not unintentionally modify variables outside of their own scope. This is accomplished by enclosing your function's main routine with the setlocal and endlocal statements as shown in the example above. Unfortunately things get a little more complicated when two or more arguments are passed by reference and those arguments need to be read by your function (as opposed to just being assigned values). This is best illustrated by the Swap function shown below. Protecting Arguments When passing two or more arguments by reference where those arguments need to be read, care must be taken not to destroy any of the arguments before they have all been read. Consider this example below. 01. @echo off & setlocal ENABLEEXTENSIONS 02. set a=one 03. set b=two 04. echo/Before call :swap a b 05. call :Swap a b 06. echo/After call 1 :swap a b 07. call :Swap b a 08. echo/After call 2 :swap b a 09. 10. goto :EOF 11. 12. :Swap 13. setlocal 14. call set a=%%%1%% 15. call set b=%%%2%% 16. endlocal & set "%1=%b%" & set "%2=%a%" & goto :EOF The above example displays:- Before call :swap a b After call 1 :swap a b After call 2 :swap b a This function is supposed to swap the contents of two variables. Notice it succeed the first time, but failed on the second. This was caused by variable names outside of the function clashing with duplicate names inside the function. Specifically, this is what went wrong:- Line 07 called Swap, the first argument is b, the second a. Line 14 is expanded twice because of the call command, after the second expansion, the line equates to set a=one, and once this command is executed, a is overwritten. Line 15 is also expanded twice and equates to set b=one, in other words both a and b are now the one The usual workaround for this problem is to use variable names that are unique to your function by preceeding all function variables with the function name separated by a period. However, if using that approach, it's actually only necessary to use unique names for vulnerable variables. Rewriting lines 14-16 of the Area function as shown below would prevent any arguments being overwritten before they had been saved. 14. call set Swap.a=%%%1%% 15. call set b=%%%2%% 16. endlocal&set %1=%b%&set %2=%Swap.a%&goto :EOF This method has several drawbacks. Firstly, you must never use a period in any variable name outside of your functions. Secondly, if the function doesn't have a really short name and reads a number of variables by reference, the number of lines of code in the function can double if you want to avoid 'long' lines of code. An alternative method is to read the variables with the FOR /F command using a delimiter character not present in any of the argument values. Using this method the Swap function could be rewritten as follows:- 12. :Swap 13. setlocal ENABLEEXTENSIONS 14. for /f "tokens=1-2 delims=¬" %%a in ('echo/%%%1%%¬%%%2%%') do ( 15. set a=%%a&set b=%%b 16. ) 17. endlocal&set %1=%b%&set %2=%a%&goto :EOF The delimiter character is a '¬' (ASCII 172, which looks like a back-to-front 'L' on its side). It was chosen because it's rarely used and it appears on a UK keyboard (above the TAB key). If you don't have this key, you can type it by holding down the Alt key and typing 172 on the numeric keypad. The only drawback of this method being your variables must never contain the delimiter character otherwise you may obtain incorrect results. This issue was covered in alt.msdos.batch.nt in a thread titled "Function parameters". ●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●● Using the Functions(函数的使用) Copy the Function To use any of the functions, just copy and paste them to the end of your batch file. To prevent the function(s) from being executed after your main batch file code has run, add goto :EOF after your main batch file code but before the function(s). For example:- Example 1a <-- Your main batch file code goes here goto :EOF <-- 1st function here <-- 2nd function here <-- and so on... Calling the Function The documentation for each function describes the number of required and optional parameters, the type of data each parameter should contain and whether the parameter must be passed 'by value' or 'by reference'. Both terms are used very loosely here and the reason is covered in great detail in the next section. Suffice to say that to pass a variable by value, call the function with a constant or expanded variable. And to pass by reference, call the function with the name of a variable. By Value To pass a parameter 'by value', either call the function with a constant or an expanded variable that contains the value. As an example, the Sleep function expects one parameter (a number of seconds) to be passed by value. Here are three ways to call the Sleep function with the value 9:- Example 2a call :Sleep 9 Example 2b set AnyVarName=9 call :Sleep %AnyVarName% Example 2c call :Sleep %1 Notes: In example 2b, practically any variable name could have been used. Example 2c assumes the value of 9 was passed to the batch file as a commandline parameter. By Reference To pass a value 'by reference' simply use the name of a variable. As an example, the GetDate function expects three parameters, all passed by reference. Here's how to call the GetDate function and use the 'returned' values:- Example 3a call :GetDate yy mm dd echo/Todays date is: %yy%-%mm%-%dd% Note that although example 3a used the variable names yy, mm and dd, practically any variable names could have been used. For instance, example 3b is functionally equivalent to example 3a (but not so easy to understand). Example 3b call :GetDate x y z echo/Todays date is: %x%-%y%-%z% ●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●● 应用举例: DateToDOW The DateToDOW function returns the day of week number for a given calendar date.. ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: :DateToDOW %yy% %mm% %dd% dow :: :: By: Ritchie Lawrence, 2003-04-29. Version 1.1 :: :: Func: Creates a day of week number from a calendar date, where 1 = Mon :: and 7 = Sun. For NT4/2000/XP/2003. :: :: Args: %1 year component to be converted, 2 or 4 digits (by val) :: %2 month component to be converted, leading zero ok (by val) :: %3 day of month to be converted, leading zero ok (by val) :: %4 var to receive day of week number, 1 to 7 (by ref) ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: setlocal ENABLEEXTENSIONS set yy=%1&set mm=%2&set dd=%3 if 1%yy% LSS 200 if 1%yy% LSS 170 (set yy=20%yy%) else (set yy=19%yy%) set /a dd=100%dd%%%100,mm=100%mm%%%100 set /a z=14-mm,z/=12,y=yy+4800-z,m=mm+12*z-3,dow=153*m+2 set /a dow=dow/5+dd+y*365+y/4-y/100+y/400-2472630,dow%%=7,dow+=1 endlocal&set %4=%dow%&goto :EOF ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: Parameters %1 year component to be converted, 2 or 4 digits (by val) %2 month component to be converted, leading zero ok (by val) %3 day of month to be converted, leading zero ok (by val) %4 var to receive day of week number, 1 to 7 (by ref) Return Values See parameters above. Example @echo off & setlocal ENABLEEXTENSIONS call :GetDate y m d call :DateToDOW %y% %m% %d% dow call :DayName %dow% day echo/Today is %day% goto :EOF Remarks The DateToWeek function also returns day of week (in addition to year and month). See Also DateToWeek, DayName, DayNumber |
|
| 第3楼 plp626 | 发表于 2008-04-02 00:22 |
| 银牌会员 发帖 1,020 积分 2,278 | |
|
真就这么无动于衷吗?
fastslz zh159 HAT 26933062 你们在线呀!我就不信你们也不感兴趣. 有多少人因为这样相继离去,(当然我不会的,∵我还没成为高手) |
|
| 第4楼 HAT | 发表于 2008-04-02 01:01 |
| 版主 发帖 5,017 积分 9,023 | |
|
别人写的,我帮忙贴一下吧:
|
|
| 第5楼 Shinaterry | 发表于 2008-04-02 14:35 |
| 初级用户 发帖 51 积分 97 | |
![]() 弱弱请教一下.. 假如A.bat内容如下: 现时B.bat能否利用call直接调用A.bat->:c(标签)? [ Last edited by Shinaterry on 2008-4-2 at 02:38 PM ] |
|
| 第6楼 huahua0919 | 发表于 2008-04-02 14:48 |
| 银牌会员 发帖 780 积分 1,608 | |
|
不是无动于衷,BAT没什么函数及方法之类的东东,全是靠命令堆积起来的,变化的只是头脑,缺少的只是经验!如果真的想了解函数库,那还不如多了解JS,VBS,JAVA,C的函数,及相关联的组建,如COM.DLL之!
|
|
| 第7楼 Shinaterry | 发表于 2008-04-02 15:30 |
| 初级用户 发帖 51 积分 97 | |
|
谢谢两位! abcd 兄的方法正正是我原先所使用的, 因为觉得笨拙, 所以特意请教有没有方法可直接调用..
看来楼主, 看透我的意图, 因为这样"批处理函数库"的存在才有更大意义.. ![]() [ Last edited by Shinaterry on 2008-4-2 at 03:36 PM ] |
|
| 第8楼 zh159 | 发表于 2008-04-02 17:04 |
| 金牌会员 发帖 1,467 积分 3,687 | |
|
真正常用的子过程并不多,而且不一定能通用,或多或少都需要适当修改,基本上是根据实际应用再编写
|
|
| 第9楼 knoppix7 | 发表于 2008-04-07 19:26 |
| 银牌会员 发帖 634 积分 1,287 来自 cmd.exe | |
|
个人感觉:
函数库很有必要. 貌似目前更需要"方法库".给人写了一堆代码。该不会的还不会.(BC到搜索都懒得用.同一个问题回答N便很让人烦..) 直接给出大致方法.他们自己发挥去. |
|
| 第10楼 plp626 | 发表于 2008-04-23 16:04 |
| 银牌会员 发帖 1,020 积分 2,278 | |
| 第11楼 plp626 | 发表于 2008-04-23 16:05 |
| 银牌会员 发帖 1,020 积分 2,278 | |
|
.....
[ Last edited by plp626 on 2008-4-25 at 07:15 PM ] |
|
| 第12楼 metoo | 发表于 2008-04-24 21:04 |
| 初级用户 发帖 93 积分 195 | |
|
发了一个用来删除文件的
http://www.cn-dos.net/forum/viewthread.php?tid=39723&fpage=2 。。貌似没多少人感兴趣 - -! 这个可以直接加参数用call调用,当然要调用的话重启那段代码可以去掉 [ Last edited by metoo on 2008-4-24 at 09:07 PM ] |
|
| 第13楼 slore | 发表于 2008-04-24 21:07 |
| 铂金会员 发帖 2,478 积分 5,212 | |
|
还是用DEL 和RD命令?又不能强删,所以实用性不高呀
UNLOCKER,右键很方便…… |
|
| 第14楼 metoo | 发表于 2008-04-24 21:09 |
| 初级用户 发帖 93 积分 195 | |
|
加上了重命名后重启删除,确实实用性一般,我写这也就是想作为一个函数调用的 p终究不是万能的
正在考虑寻找一些更加霸道的命令加入代码,这个只能算一个雏形把,慢慢完善 [ Last edited by metoo on 2008-4-24 at 09:10 PM ] |
|
| 第15楼 metoo | 发表于 2008-04-24 21:13 |
| 初级用户 发帖 93 积分 195 | |
|
还有一段查看网络性息的事别人写的
|
|
| 1 2 3 下一页 |
|
[ 联系联盟系统管理团队 -
中国DOS联盟 -
标准版 ] Sponsored by ifanr Inc | © 2001–2023 |