Windows .bat/.cmd function library in own file?

后端 未结 6 2039
春和景丽
春和景丽 2021-02-05 14:50

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 .

6条回答
  •  夕颜
    夕颜 (楼主)
    2021-02-05 15:30

    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.

    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%.
    • 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

    How it works:

    • Creates a temporary file at %TEMP% (won´t work if %TEMP% is not set)
    • Copies itself to this temporary file
    • Searches for each library in these paths:
      • original batch file path
      • %BatchLibraryPath%
      • Any other path listed in %_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
    • 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)
    • Returns errorlevel if any error occurs

    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)

    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 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:

    SetBatchLibraryPath.bat

    setx BatchLibraryPath "%~dp0"
    pause
    

提交回复
热议问题