Windows。bat /。cmd函数库在自己的文件中?

时间:2022-06-08 04:22:48

there is a nice way to build functions in DOS .bat/.cmd script. To modularize some installation scripts, it would be nice to include a file with a library of functions into an .bat/.cmd script.

有一种在DOS .bat/中构建函数的好方法。cmd脚本。要模块化一些安装脚本,最好在.bat/中包含一个包含函数库的文件。cmd脚本。

what I tried was:

我尝试的是:

mainscript.bat

mainscript.bat

call library.bat

call:function1

library.bat

library.bat

goto:eof

:stopCalipri    -- stop alle prozesse die mit calipri zu tun haben
::                 -- %~1: argument description here
SETLOCAL
REM.--function body here
set LocalVar1=dummy
set LocalVar2=dummy

echo "Called function successfully :)"

(ENDLOCAL & REM -- RETURN VALUES
   IF "%~1" NEQ "" SET %~1=%LocalVar1%
   IF "%~2" NEQ "" SET %~2=%LocalVar2%
)
GOTO:EOF

When I call mainscript.bat then I get following output: Das Sprungziel - function1 wurde nicht gefunden.

当我叫mainscript。然后我得到如下输出:Das Sprungziel - function1 wurde nicht gefunden。

What means more or less: Can not find jump point named function1

什么意思或多或少:不能找到跳点命名的function1 !

Any ideas, or is this not possible?

有什么想法,或者这是不可能的?

5 个解决方案

#1


11  

It's possible, and there are some different ways to do it.

这是可能的,有很多不同的方法。

1) Copy&Paste the complete "Library" into each of your files Works, but it's not really a library, and it's a horror to change/correct a library function in all files

1)将完整的“库”复制到每个文件中,但它并不是真正的库,在所有文件中更改/纠正库函数是一种恐怖。

2) include a library via call-wrapper

2)通过调用包装器包含库

call batchLib.bat :length result "abcdef"

and batchLib.bat starts with

和batchLib。蝙蝠开始

call %* 
exit /b
...
:length
...

Easy to program, but very slow, as each library call loads the library batch, and possible problems with the parameters.

容易编程,但很慢,因为每个库调用加载库批,以及可能的参数问题。

3) A "self-loading" library BatchLibrary or how to include batch files

3)“自加载”库批处理库或如何包含批处理文件

It creates each time a temporary batch file, combined of the own code and the library code.
It do some advanced functions at the library startup like secure parameter access. But in my opinion it's also easy to use

它每次都创建一个临时批处理文件,将自己的代码和库代码组合在一起。它在库启动时执行一些高级功能,如安全参数访问。但在我看来,它也很容易使用。

A user script sample

用户脚本示例

@echo off
REM 1. Prepare the BatchLibrary for the start command
call BatchLib.bat

REM 2. Start of the Batchlib, acquisition of the command line parameters, activates the code with the base-library
<:%BL.Start%

rem  Importing more libraries ...
call :bl.import "bl_DateTime.bat"
call :bl.import "bl_String.bat"

rem Use library functions
call :bl.String.Length result abcdefghij
echo len=%result%

EDIT: Another way is ...

编辑:另一种方式是……

4) A macro library

4)一个宏观库

You could use batch-macros, it's easy to include and to use them.

您可以使用批处理宏,很容易包含并使用它们。

call MacroLib.bat

set myString=abcdef
%$strLen% result,myString
echo The length of myString is %result%

But it's tricky to build the macros!
More about the macro technic at Batch "macros" with arguments

但是构建宏是很棘手的!更多关于带参数的批处理“宏”的宏技术

MacroLibrary.bat

MacroLibrary.bat

set LF=^


::Above 2 blank lines are required - do not remove
set ^"\n=^^^%LF%%LF%^%LF%%LF%^^"
:::: StrLen pString pResult
set $strLen=for /L %%n in (1 1 2) do if %%n==2 (%\n%
        for /F "tokens=1,2 delims=, " %%1 in ("!argv!") do (%\n%
            set "str=A!%%~2!"%\n%
              set "len=0"%\n%
              for /l %%A in (12,-1,0) do (%\n%
                set /a "len|=1<<%%A"%\n%
                for %%B in (!len!) do if "!str:~%%B,1!"=="" set /a "len&=~1<<%%A"%\n%
              )%\n%
              for %%v in (!len!) do endlocal^&if "%%~b" neq "" (set "%%~1=%%v") else echo %%v%\n%
        ) %\n%
) ELSE setlocal enableDelayedExpansion ^& set argv=,

#2


1  

There is an easier way to load the library functions each time the main file is executed. For example:

每当执行主文件时,都有一种更简单的方法来加载库函数。例如:

@echo off
rem If current code was restarted, skip library loading part
if "%_%" == "_" goto restart
rem Copy current code and include any desired library
copy /Y %0.bat+lib1.bat+libN.bat %0.full.bat
rem Set the restart flag
set _=_
rem Restart current code
%0.full %*
:restart
rem Delete the restart flag
set _=
rem Place here the rest of the batch file
rem . . . . .
rem Always end with goto :eof, because the library functions will be loaded
rem after this code!
goto :eof

#3


1  

I came up with a simple solution for using external libraries with batch files, and I would like to ask you guys to test it and find possible bugs.

我提出了一个使用批处理文件的外部库的简单解决方案,我想请大家测试一下,并找出可能的bug。

How to use:

如何使用:

  • Create a library (a folder with library batch files inside)
  • 创建一个库(包含库批文件的文件夹)
  • Put this header before any batch file you create that uses a library.
  • 将此头放在使用库创建的任何批处理文件之前。

Principle of operation:

工作原理:

  • Creates a temporary file with the libraries copied at the end of the file. It searches for the libraries in all paths listed in %_IncludesPath%.
  • 使用在文件末尾复制的库创建一个临时文件。它在%_IncludesPath%中列出的所有路径中搜索库。
  • For it to work, the libraries have to be in a "funcion" structure. Example libraries can be found at: http://www.commandline.co.uk/lib/treeview/index.php?contents.php&../treeview/main.php
  • 要使它发挥作用,图书馆必须采用“函数式”结构。示例库可以在:http://www.commandline.co.uk/lib/treeview/index.php?

How it works:

它是如何工作的:

  • Creates a temporary file at %TEMP% (won´t work if %TEMP% is not set)
  • 创建一个临时文件%临时%(赢得´t工作如果不设置%临时%)
  • Copies itself to this temporary file
  • 将自己复制到这个临时文件
  • Searches for each library in these paths:
    • original batch file path
    • 原始的批处理文件路径
    • %BatchLibraryPath%
    • % BatchLibraryPath %
    • Any other path listed in %_IncludesPath%
    • %_IncludesPath%中列出的任何其他路径
  • 在这些路径中搜索每个库:原始批处理文件路径%BatchLibraryPath% % % % %中列出的任何其他路径%_IncludesPath%
  • Appends these libraries to the temporary file
  • 将这些库附加到临时文件
  • Runs the temporary file
  • 的临时文件
  • exits and deletes temporary file
  • 退出并删除临时文件。

Advantages:

优点:

  • Passed command line arguments work perfectly
  • 通过的命令行参数工作得很好
  • No need to end the user code with any special command
  • 不需要使用任何特殊的命令来结束用户代码
  • Libraries can be anywhere in the computer
  • 图书馆可以在计算机的任何地方
  • Libraries can be in shared folders with UNC paths
  • 库可以放在带有UNC路径的共享文件夹中。
  • You can have libraries in different paths and all of them will be added (if same library is found in different paths, the one at the left-most path in %_IncludesPath% is used)
  • 您可以在不同的路径中有库,并将它们全部添加(如果在不同的路径中找到相同的库,则使用%_IncludesPath%中最左边的路径)
  • Returns errorlevel if any error occurs
  • 如果发生任何错误,返回errorlevel

Code:

代码:

  • Here is an example: for this to work you must have the Example.bat library in the Your_batch_file.bat folder (or in one of the %_IncludesPath% folders)
  • 这里有一个例子:要让它工作,你必须有这个例子。bat库位于Your_batch_file中。bat文件夹(或%_IncludesPath%文件夹中的一个)

Your_batch_file.bat

Your_batch_file.bat

@echo off & setlocal EnableExtensions 
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
::Your code starts in :_main
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
::   v1.5 - 01/08/2015 - by Cyberponk - Fixed returning to original path when using RequestAdminElevation
::   v1.4 - 25/05/2015 - by Cyberponk 
::   This module includes funcions from included libraries so that you can call
::   them inside the :_main program
::
::   Options
set "_DeleteOnExit=0" &:: if 1, %_TempFile% will be deleted on exit (set to 0 if using library RequestAdminElevation)
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
(if "%BatchLibraryPath%"=="" set "BatchLibraryPath=.") &set "_ErrorCode=" &set "#include=call :_include" 
set _LibPaths="%~dp0";"%BatchLibraryPath%"&set "_TempFile=%TEMP%\_%~nx0" 
echo/@echo off ^& CD /D "%~dp0" ^& goto:_main> "%_TempFile%"  || (echo/Unable to create "%_TempFile%" &echo/Make sure the %%TEMP%% path has Read/Write access and that a file with the same name doesn't exist already &endlocal &md; 2>nul &goto:eof ) &type "%~dpf0" >> "%_TempFile%" &echo/>>"%_TempFile%" &echo goto:eof>>"%_TempFile%" &call :_IncludeLibraries
(if "%_ErrorCode%"=="" (call "%_TempFile%" %*) else (echo/%_ErrorCode% &pause)) & (if "%_DeleteOnExit%"=="1" (del "%_TempFile%")) & endlocal & (if "%_ErrorCode%" NEQ "" (set "_ErrorCode=" & md; 2>nul)) &goto:eof 
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:_include lib
set "lib=%~1.bat" &set "_included="
  (if EXIST "%lib%" ( set "_included=1" &echo/>> "%_TempFile%" &type "%lib%" >> "%_TempFile%" & goto:eof )) & for %%a in (%_LibPaths%) do (if EXIST "%%~a\%lib%" ( set "_included=1" &echo/>> "%_TempFile%" &type "%%~a\%lib%" >> "%_TempFile%" &goto:endfor))
  :endfor
  (if NOT "%_included%"=="1" ( set "_ErrorCode=%_ErrorCode%Library '%~1.bat' not fount, aborting...&echo/Verify if the environment variable BatchLibraryPath is pointing to the right path - and has no quotes - or add a custom path to line 25&echo/" )) &goto:eof
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:_IncludeLibraries - Your included libraries go here
::::::::::::::::::::::::::::::::::::::
:: You can add custom paths to this variable:
  set _LibPaths=%_LibPaths%; C:\; \\SERVER\folder

:: Add a line for each library you want to include (use quotes for paths with space)
:: Examples:
::  %#include% beep
::  %#include% Network\GetIp
::  %#include% "Files and Folders\GetDirStats"
::  %#include% "c:\Files and Folders\GetDriveSize"
::  %#include% "\\SERVER\batch\SendHello"

  %#include% Example

goto:eof
::End _IncludeLibraries

:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:_main - Your code goes here
::::::::::::::::::::::::::::::::::::::

echo/Example code:
call :Example "It works!"

echo/____________________
echo/Work folder: %CD%
echo/
echo/This file: %0
echo/
echo/Library paths: %_LibPaths%
echo/____________________
echo/Argument 1 = %1
echo/Argument 2 = %2
echo/All Arguments = %*
echo/____________________

pause

.

Example.bat

Example.bat

:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:Example msg
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
setlocal ENABLEEXTENSIONS & set "msg=%1"
  echo/%msg%
endlocal & goto :EOF
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

If you want an easy way to set the %BatchLibraryPath%, just put this file inside your Library path and run it before running Your_batch_file.bat. This setting is persistent on reboots, so you run this once only:

如果您想要一种简单的方法来设置%BatchLibraryPath%,只需将这个文件放在库路径中,并在运行您的_batch_file.bat之前运行它。这个设置在重新启动时是持久的,所以您只运行一次:

SetBatchLibraryPath.bat

SetBatchLibraryPath.bat

setx BatchLibraryPath "%~dp0"
pause

#4


0  

Another solution would be to temporary append the library functions to the running batch file.

The original file can be saved in a temporary file before the change and restored when finished. This has the downside that you need to call the :deimport function at the end to restore the file and remove the temporary file. You also need to be able to write to the batch file and the folder you are currently in.

另一个解决方案是将库函数临时附加到正在运行的批处理文件中。在更改之前,可以将原始文件保存在临时文件中,并在完成后恢复。这有一个缺点,您需要调用:deimport函数在结束时恢复文件并删除临时文件。您还需要能够写入批处理文件和当前所在的文件夹。

demo.bat

demo.bat

@ECHO OFF
:: internal import call or external import call via wrapper function
CALL:IMPORT test.bat "C:\path with spaces\lib 2.bat"
:: external import call
::CALL importer.bat "%~f0%" test.bat "C:\path with spaces\lib 2.bat"

CALL:TEST
CALL:LIB2TEST

CALL:DEIMPORT
GOTO:EOF

:: Internal version of the importer
:IMPORT
SETLOCAL
IF NOT EXIST "%~f0.tmp" COPY /Y "%~f0" "%~f0.tmp">NUL
SET "PARAMS=%*"
SET "PARAMS=%PARAMS:.bat =.bat+%"
SET "PARAMS=%PARAMS:.bat" =.bat"+%"
COPY /Y "%~f0"+%PARAMS% "%~f0">NUL
ENDLOCAL
GOTO:EOF

:: wrapper function for external version call
:::IMPORT
::CALL import.bat "%~f0" %*
::GOTO:EOF

:: Internal version of the deimporter
:DEIMPORT
IF EXIST "%~f0.tmp" (
  COPY /Y "%~f0.tmp" "%~f0">NUL
  DEL "%~f0.tmp">NUL
)
GOTO:EOF


test.bat

test.bat

:test
ECHO output from test.bat
GOTO:EOF


C:\path with spaces\lib 2.bat

C:\ \ lib 2.蝙蝠路径与空间

:LIB2TEST
ECHO output from lib 2.bat
GOTO:EOF


Alternatively using the external version. Note this imports the deimport function so make sure you remove it in the demo.bat file.

或者使用外部版本。注意,这将导入deimport函数,所以请确保在演示中删除它。bat文件。

import.bat

import.bat

:: External version of the importer
SETLOCAL EnableDelayedExpansion
IF NOT EXIST "%~f1.tmp" COPY /Y "%~f1" "%~f1.tmp">NUL
SET "PARAMS=%*"
SET "PARAMS=!PARAMS:"%~f1" =!"
SET "PARAMS=%PARAMS:.bat =.bat+%"
SET "PARAMS=%PARAMS:.bat" =.bat"+%"
COPY /Y "%~f1"+%PARAMS% "%~f1">NUL

:: external version of the importer - remove the internal one before use!
ECHO :DEIMPORT>>"%~f1"
ECHO IF EXIST ^"%%~f0.tmp^" ^(>>"%~f1"
ECHO.  COPY /Y ^"%%~f0.tmp^" ^"%%~f0^"^>NUL>>"%~f1"
ECHO.  DEL ^"%%~f0.tmp^"^>NUL>>"%~f1"
ECHO ^)>>"%~f1"
ECHO GOTO:EOF>>"%~f1"
ENDLOCAL
GOTO:EOF

#5


0  

okay... quick & dirty because I'm a UNIX guy... create your "library" file

好吧……快速和肮脏,因为我是一个UNIX的人…创建你的“图书馆”文件

  1 @ECHO OFF<br>
  2 SETLOCAL ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION & PUSHD<br>
  3 :: -----------------------------------------------<br>
  4 :: $Id$<br>
  5 :: <br>
  6 :: NAME:<br>
  7 :: PURPOSE:<br>
  8 :: NOTES:<br>
  9 :: <br>
 10 :: INCLUDES   --------------------------------- --<br>
 11 :: DEFINES    --------------------------------- --<br>
 12 :: VARIABLES  --------------------------------- --<br>
 13 :: MACROS     --------------------------------- --<br>
 14 <br>
 15 GOTO :MAINLINE<br>
 16 <br>
 17 :: FUNCTIONS  --------------------------------- --<br>
 18 <br>
 19 :HEADER<br>
 20     ECHO ^&lt;HTML^&gt;<br>
 21     ECHO ^&lt;HEAD^&gt;<br>
 22     ECHO    ^&lt;TITLE^&gt;%1^&lt;/TITLE^&gt;<br>
 23     ECHO ^&lt;/HEAD^&gt;<br>
 24     ECHO ^&lt;BODY^&gt;<br>
 25     GOTO :EOF<br>
 26 <br>
 27 :TRAILER<br>
 28     ECHO ^&lt;/BODY^&gt;<br>
 29     ECHO ^&lt;/HTML^&gt;<br>
 30     GOTO :EOF<br>
 31 <br>
 32 :: MAINLINE   --------------------------------- --<br>
 33 :MAINLINE<br>
 34 <br>
 35 IF /I "%1" == "HEADER"  CALL :HEADER %2<br>
 36 IF /I "%1" == "TRAILER" CALL :TRAILER<br>
 37 <br>
 38 ENDLOCAL & POPD<br>
 39 :: HISTORY     ------------------------------------<br>
 40 :: $Log$<br>
 41 :: END OF FILE --------------------------------- --<br>

this should be pretty straight-forward for you... at line 15 we make the jump to mainline to begin actual execution. At lines 19 and 27 we create entry points for our routines. At lines 35 and 36 are calls to the internal routines.

这对你来说应该很直接……在第15行,我们将跳转到主线以开始实际执行。在第19行和第27行,我们为例程创建了入口点。第35行和第36行是对内部例程的调用。

now, you build the file that will call the library routines..

现在,构建将调用库例程的文件。

  1 @ECHO OFF<br>
  2 SETLOCAL ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION & PUSHD<br>
  3 :: -----------------------------------------------<br>
  4 :: $Id$<br>
  5 :: <br>
  6 :: NAME:<br>
  7 :: PURPOSE:<br>
  8 :: NOTES:<br>
  9 :: <br>
 10 :: INCLUDES   --------------------------------- --<br>
 11 <br>
 12 SET _LIB_=PATH\TO\LIBRARIES\LIBNAME.BAT<br>
 13 <br>
 14 :: DEFINES    --------------------------------- --<br>
 15 :: VARIABLES  --------------------------------- --<br>
 16 :: MACROS     --------------------------------- --<br>
 17 <br>
 18 GOTO :MAINLINE<br>
 19 <br>
 20 :: FUNCTIONS  --------------------------------- --<br>
 21 :: MAINLINE   --------------------------------- --<br>
 22 :MAINLINE<br>
 23 <br>
 24 call %_LIB_% header foo<br>
 25 call %_LIB_% trailer<br>
 26 <br>
 27 ENDLOCAL & POPD<br>
 28 :: HISTORY     ------------------------------------<br>
 29 :: $Log$<br>
 30 :: END OF FILE --------------------------------- --<br>
<br>

line 12 "imports" the "library"... actually it's just syntactic sugar that makes the subsequent calls easier...

第12行“导入”“库”…实际上,只是语法上的糖让后面的调用更容易……

#1


11  

It's possible, and there are some different ways to do it.

这是可能的,有很多不同的方法。

1) Copy&Paste the complete "Library" into each of your files Works, but it's not really a library, and it's a horror to change/correct a library function in all files

1)将完整的“库”复制到每个文件中,但它并不是真正的库,在所有文件中更改/纠正库函数是一种恐怖。

2) include a library via call-wrapper

2)通过调用包装器包含库

call batchLib.bat :length result "abcdef"

and batchLib.bat starts with

和batchLib。蝙蝠开始

call %* 
exit /b
...
:length
...

Easy to program, but very slow, as each library call loads the library batch, and possible problems with the parameters.

容易编程,但很慢,因为每个库调用加载库批,以及可能的参数问题。

3) A "self-loading" library BatchLibrary or how to include batch files

3)“自加载”库批处理库或如何包含批处理文件

It creates each time a temporary batch file, combined of the own code and the library code.
It do some advanced functions at the library startup like secure parameter access. But in my opinion it's also easy to use

它每次都创建一个临时批处理文件,将自己的代码和库代码组合在一起。它在库启动时执行一些高级功能,如安全参数访问。但在我看来,它也很容易使用。

A user script sample

用户脚本示例

@echo off
REM 1. Prepare the BatchLibrary for the start command
call BatchLib.bat

REM 2. Start of the Batchlib, acquisition of the command line parameters, activates the code with the base-library
<:%BL.Start%

rem  Importing more libraries ...
call :bl.import "bl_DateTime.bat"
call :bl.import "bl_String.bat"

rem Use library functions
call :bl.String.Length result abcdefghij
echo len=%result%

EDIT: Another way is ...

编辑:另一种方式是……

4) A macro library

4)一个宏观库

You could use batch-macros, it's easy to include and to use them.

您可以使用批处理宏,很容易包含并使用它们。

call MacroLib.bat

set myString=abcdef
%$strLen% result,myString
echo The length of myString is %result%

But it's tricky to build the macros!
More about the macro technic at Batch "macros" with arguments

但是构建宏是很棘手的!更多关于带参数的批处理“宏”的宏技术

MacroLibrary.bat

MacroLibrary.bat

set LF=^


::Above 2 blank lines are required - do not remove
set ^"\n=^^^%LF%%LF%^%LF%%LF%^^"
:::: StrLen pString pResult
set $strLen=for /L %%n in (1 1 2) do if %%n==2 (%\n%
        for /F "tokens=1,2 delims=, " %%1 in ("!argv!") do (%\n%
            set "str=A!%%~2!"%\n%
              set "len=0"%\n%
              for /l %%A in (12,-1,0) do (%\n%
                set /a "len|=1<<%%A"%\n%
                for %%B in (!len!) do if "!str:~%%B,1!"=="" set /a "len&=~1<<%%A"%\n%
              )%\n%
              for %%v in (!len!) do endlocal^&if "%%~b" neq "" (set "%%~1=%%v") else echo %%v%\n%
        ) %\n%
) ELSE setlocal enableDelayedExpansion ^& set argv=,

#2


1  

There is an easier way to load the library functions each time the main file is executed. For example:

每当执行主文件时,都有一种更简单的方法来加载库函数。例如:

@echo off
rem If current code was restarted, skip library loading part
if "%_%" == "_" goto restart
rem Copy current code and include any desired library
copy /Y %0.bat+lib1.bat+libN.bat %0.full.bat
rem Set the restart flag
set _=_
rem Restart current code
%0.full %*
:restart
rem Delete the restart flag
set _=
rem Place here the rest of the batch file
rem . . . . .
rem Always end with goto :eof, because the library functions will be loaded
rem after this code!
goto :eof

#3


1  

I came up with a simple solution for using external libraries with batch files, and I would like to ask you guys to test it and find possible bugs.

我提出了一个使用批处理文件的外部库的简单解决方案,我想请大家测试一下,并找出可能的bug。

How to use:

如何使用:

  • Create a library (a folder with library batch files inside)
  • 创建一个库(包含库批文件的文件夹)
  • Put this header before any batch file you create that uses a library.
  • 将此头放在使用库创建的任何批处理文件之前。

Principle of operation:

工作原理:

  • Creates a temporary file with the libraries copied at the end of the file. It searches for the libraries in all paths listed in %_IncludesPath%.
  • 使用在文件末尾复制的库创建一个临时文件。它在%_IncludesPath%中列出的所有路径中搜索库。
  • For it to work, the libraries have to be in a "funcion" structure. Example libraries can be found at: http://www.commandline.co.uk/lib/treeview/index.php?contents.php&../treeview/main.php
  • 要使它发挥作用,图书馆必须采用“函数式”结构。示例库可以在:http://www.commandline.co.uk/lib/treeview/index.php?

How it works:

它是如何工作的:

  • Creates a temporary file at %TEMP% (won´t work if %TEMP% is not set)
  • 创建一个临时文件%临时%(赢得´t工作如果不设置%临时%)
  • Copies itself to this temporary file
  • 将自己复制到这个临时文件
  • Searches for each library in these paths:
    • original batch file path
    • 原始的批处理文件路径
    • %BatchLibraryPath%
    • % BatchLibraryPath %
    • Any other path listed in %_IncludesPath%
    • %_IncludesPath%中列出的任何其他路径
  • 在这些路径中搜索每个库:原始批处理文件路径%BatchLibraryPath% % % % %中列出的任何其他路径%_IncludesPath%
  • Appends these libraries to the temporary file
  • 将这些库附加到临时文件
  • Runs the temporary file
  • 的临时文件
  • exits and deletes temporary file
  • 退出并删除临时文件。

Advantages:

优点:

  • Passed command line arguments work perfectly
  • 通过的命令行参数工作得很好
  • No need to end the user code with any special command
  • 不需要使用任何特殊的命令来结束用户代码
  • Libraries can be anywhere in the computer
  • 图书馆可以在计算机的任何地方
  • Libraries can be in shared folders with UNC paths
  • 库可以放在带有UNC路径的共享文件夹中。
  • You can have libraries in different paths and all of them will be added (if same library is found in different paths, the one at the left-most path in %_IncludesPath% is used)
  • 您可以在不同的路径中有库,并将它们全部添加(如果在不同的路径中找到相同的库,则使用%_IncludesPath%中最左边的路径)
  • Returns errorlevel if any error occurs
  • 如果发生任何错误,返回errorlevel

Code:

代码:

  • Here is an example: for this to work you must have the Example.bat library in the Your_batch_file.bat folder (or in one of the %_IncludesPath% folders)
  • 这里有一个例子:要让它工作,你必须有这个例子。bat库位于Your_batch_file中。bat文件夹(或%_IncludesPath%文件夹中的一个)

Your_batch_file.bat

Your_batch_file.bat

@echo off & setlocal EnableExtensions 
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
::Your code starts in :_main
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
::   v1.5 - 01/08/2015 - by Cyberponk - Fixed returning to original path when using RequestAdminElevation
::   v1.4 - 25/05/2015 - by Cyberponk 
::   This module includes funcions from included libraries so that you can call
::   them inside the :_main program
::
::   Options
set "_DeleteOnExit=0" &:: if 1, %_TempFile% will be deleted on exit (set to 0 if using library RequestAdminElevation)
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
(if "%BatchLibraryPath%"=="" set "BatchLibraryPath=.") &set "_ErrorCode=" &set "#include=call :_include" 
set _LibPaths="%~dp0";"%BatchLibraryPath%"&set "_TempFile=%TEMP%\_%~nx0" 
echo/@echo off ^& CD /D "%~dp0" ^& goto:_main> "%_TempFile%"  || (echo/Unable to create "%_TempFile%" &echo/Make sure the %%TEMP%% path has Read/Write access and that a file with the same name doesn't exist already &endlocal &md; 2>nul &goto:eof ) &type "%~dpf0" >> "%_TempFile%" &echo/>>"%_TempFile%" &echo goto:eof>>"%_TempFile%" &call :_IncludeLibraries
(if "%_ErrorCode%"=="" (call "%_TempFile%" %*) else (echo/%_ErrorCode% &pause)) & (if "%_DeleteOnExit%"=="1" (del "%_TempFile%")) & endlocal & (if "%_ErrorCode%" NEQ "" (set "_ErrorCode=" & md; 2>nul)) &goto:eof 
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:_include lib
set "lib=%~1.bat" &set "_included="
  (if EXIST "%lib%" ( set "_included=1" &echo/>> "%_TempFile%" &type "%lib%" >> "%_TempFile%" & goto:eof )) & for %%a in (%_LibPaths%) do (if EXIST "%%~a\%lib%" ( set "_included=1" &echo/>> "%_TempFile%" &type "%%~a\%lib%" >> "%_TempFile%" &goto:endfor))
  :endfor
  (if NOT "%_included%"=="1" ( set "_ErrorCode=%_ErrorCode%Library '%~1.bat' not fount, aborting...&echo/Verify if the environment variable BatchLibraryPath is pointing to the right path - and has no quotes - or add a custom path to line 25&echo/" )) &goto:eof
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:_IncludeLibraries - Your included libraries go here
::::::::::::::::::::::::::::::::::::::
:: You can add custom paths to this variable:
  set _LibPaths=%_LibPaths%; C:\; \\SERVER\folder

:: Add a line for each library you want to include (use quotes for paths with space)
:: Examples:
::  %#include% beep
::  %#include% Network\GetIp
::  %#include% "Files and Folders\GetDirStats"
::  %#include% "c:\Files and Folders\GetDriveSize"
::  %#include% "\\SERVER\batch\SendHello"

  %#include% Example

goto:eof
::End _IncludeLibraries

:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:_main - Your code goes here
::::::::::::::::::::::::::::::::::::::

echo/Example code:
call :Example "It works!"

echo/____________________
echo/Work folder: %CD%
echo/
echo/This file: %0
echo/
echo/Library paths: %_LibPaths%
echo/____________________
echo/Argument 1 = %1
echo/Argument 2 = %2
echo/All Arguments = %*
echo/____________________

pause

.

Example.bat

Example.bat

:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:Example msg
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
setlocal ENABLEEXTENSIONS & set "msg=%1"
  echo/%msg%
endlocal & goto :EOF
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

If you want an easy way to set the %BatchLibraryPath%, just put this file inside your Library path and run it before running Your_batch_file.bat. This setting is persistent on reboots, so you run this once only:

如果您想要一种简单的方法来设置%BatchLibraryPath%,只需将这个文件放在库路径中,并在运行您的_batch_file.bat之前运行它。这个设置在重新启动时是持久的,所以您只运行一次:

SetBatchLibraryPath.bat

SetBatchLibraryPath.bat

setx BatchLibraryPath "%~dp0"
pause

#4


0  

Another solution would be to temporary append the library functions to the running batch file.

The original file can be saved in a temporary file before the change and restored when finished. This has the downside that you need to call the :deimport function at the end to restore the file and remove the temporary file. You also need to be able to write to the batch file and the folder you are currently in.

另一个解决方案是将库函数临时附加到正在运行的批处理文件中。在更改之前,可以将原始文件保存在临时文件中,并在完成后恢复。这有一个缺点,您需要调用:deimport函数在结束时恢复文件并删除临时文件。您还需要能够写入批处理文件和当前所在的文件夹。

demo.bat

demo.bat

@ECHO OFF
:: internal import call or external import call via wrapper function
CALL:IMPORT test.bat "C:\path with spaces\lib 2.bat"
:: external import call
::CALL importer.bat "%~f0%" test.bat "C:\path with spaces\lib 2.bat"

CALL:TEST
CALL:LIB2TEST

CALL:DEIMPORT
GOTO:EOF

:: Internal version of the importer
:IMPORT
SETLOCAL
IF NOT EXIST "%~f0.tmp" COPY /Y "%~f0" "%~f0.tmp">NUL
SET "PARAMS=%*"
SET "PARAMS=%PARAMS:.bat =.bat+%"
SET "PARAMS=%PARAMS:.bat" =.bat"+%"
COPY /Y "%~f0"+%PARAMS% "%~f0">NUL
ENDLOCAL
GOTO:EOF

:: wrapper function for external version call
:::IMPORT
::CALL import.bat "%~f0" %*
::GOTO:EOF

:: Internal version of the deimporter
:DEIMPORT
IF EXIST "%~f0.tmp" (
  COPY /Y "%~f0.tmp" "%~f0">NUL
  DEL "%~f0.tmp">NUL
)
GOTO:EOF


test.bat

test.bat

:test
ECHO output from test.bat
GOTO:EOF


C:\path with spaces\lib 2.bat

C:\ \ lib 2.蝙蝠路径与空间

:LIB2TEST
ECHO output from lib 2.bat
GOTO:EOF


Alternatively using the external version. Note this imports the deimport function so make sure you remove it in the demo.bat file.

或者使用外部版本。注意,这将导入deimport函数,所以请确保在演示中删除它。bat文件。

import.bat

import.bat

:: External version of the importer
SETLOCAL EnableDelayedExpansion
IF NOT EXIST "%~f1.tmp" COPY /Y "%~f1" "%~f1.tmp">NUL
SET "PARAMS=%*"
SET "PARAMS=!PARAMS:"%~f1" =!"
SET "PARAMS=%PARAMS:.bat =.bat+%"
SET "PARAMS=%PARAMS:.bat" =.bat"+%"
COPY /Y "%~f1"+%PARAMS% "%~f1">NUL

:: external version of the importer - remove the internal one before use!
ECHO :DEIMPORT>>"%~f1"
ECHO IF EXIST ^"%%~f0.tmp^" ^(>>"%~f1"
ECHO.  COPY /Y ^"%%~f0.tmp^" ^"%%~f0^"^>NUL>>"%~f1"
ECHO.  DEL ^"%%~f0.tmp^"^>NUL>>"%~f1"
ECHO ^)>>"%~f1"
ECHO GOTO:EOF>>"%~f1"
ENDLOCAL
GOTO:EOF

#5


0  

okay... quick & dirty because I'm a UNIX guy... create your "library" file

好吧……快速和肮脏,因为我是一个UNIX的人…创建你的“图书馆”文件

  1 @ECHO OFF<br>
  2 SETLOCAL ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION & PUSHD<br>
  3 :: -----------------------------------------------<br>
  4 :: $Id$<br>
  5 :: <br>
  6 :: NAME:<br>
  7 :: PURPOSE:<br>
  8 :: NOTES:<br>
  9 :: <br>
 10 :: INCLUDES   --------------------------------- --<br>
 11 :: DEFINES    --------------------------------- --<br>
 12 :: VARIABLES  --------------------------------- --<br>
 13 :: MACROS     --------------------------------- --<br>
 14 <br>
 15 GOTO :MAINLINE<br>
 16 <br>
 17 :: FUNCTIONS  --------------------------------- --<br>
 18 <br>
 19 :HEADER<br>
 20     ECHO ^&lt;HTML^&gt;<br>
 21     ECHO ^&lt;HEAD^&gt;<br>
 22     ECHO    ^&lt;TITLE^&gt;%1^&lt;/TITLE^&gt;<br>
 23     ECHO ^&lt;/HEAD^&gt;<br>
 24     ECHO ^&lt;BODY^&gt;<br>
 25     GOTO :EOF<br>
 26 <br>
 27 :TRAILER<br>
 28     ECHO ^&lt;/BODY^&gt;<br>
 29     ECHO ^&lt;/HTML^&gt;<br>
 30     GOTO :EOF<br>
 31 <br>
 32 :: MAINLINE   --------------------------------- --<br>
 33 :MAINLINE<br>
 34 <br>
 35 IF /I "%1" == "HEADER"  CALL :HEADER %2<br>
 36 IF /I "%1" == "TRAILER" CALL :TRAILER<br>
 37 <br>
 38 ENDLOCAL & POPD<br>
 39 :: HISTORY     ------------------------------------<br>
 40 :: $Log$<br>
 41 :: END OF FILE --------------------------------- --<br>

this should be pretty straight-forward for you... at line 15 we make the jump to mainline to begin actual execution. At lines 19 and 27 we create entry points for our routines. At lines 35 and 36 are calls to the internal routines.

这对你来说应该很直接……在第15行,我们将跳转到主线以开始实际执行。在第19行和第27行,我们为例程创建了入口点。第35行和第36行是对内部例程的调用。

now, you build the file that will call the library routines..

现在,构建将调用库例程的文件。

  1 @ECHO OFF<br>
  2 SETLOCAL ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION & PUSHD<br>
  3 :: -----------------------------------------------<br>
  4 :: $Id$<br>
  5 :: <br>
  6 :: NAME:<br>
  7 :: PURPOSE:<br>
  8 :: NOTES:<br>
  9 :: <br>
 10 :: INCLUDES   --------------------------------- --<br>
 11 <br>
 12 SET _LIB_=PATH\TO\LIBRARIES\LIBNAME.BAT<br>
 13 <br>
 14 :: DEFINES    --------------------------------- --<br>
 15 :: VARIABLES  --------------------------------- --<br>
 16 :: MACROS     --------------------------------- --<br>
 17 <br>
 18 GOTO :MAINLINE<br>
 19 <br>
 20 :: FUNCTIONS  --------------------------------- --<br>
 21 :: MAINLINE   --------------------------------- --<br>
 22 :MAINLINE<br>
 23 <br>
 24 call %_LIB_% header foo<br>
 25 call %_LIB_% trailer<br>
 26 <br>
 27 ENDLOCAL & POPD<br>
 28 :: HISTORY     ------------------------------------<br>
 29 :: $Log$<br>
 30 :: END OF FILE --------------------------------- --<br>
<br>

line 12 "imports" the "library"... actually it's just syntactic sugar that makes the subsequent calls easier...

第12行“导入”“库”…实际上,只是语法上的糖让后面的调用更容易……