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

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


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

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

2) include a library via call-wrapper

call batchLib.bat :length result "abcdef"

and batchLib.bat starts with

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 (cached)

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 offREM 1. Prepare the BatchLibrary for the start commandcall BatchLib.batREM 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 functionscall :bl.String.Length result abcdefghijecho len=%result%

EDIT: Another way is ...

4) A macro library

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

call MacroLib.batset myString=abcdef%$strLen% result,myStringecho The length of myString is %result%

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

MacroLibrary.bat

set LF=^::Above 2 blank lines are required - do not removeset ^"\n=^^^%LF%%LF%^%LF%%LF%^^":::: StrLen pString pResultset $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=,


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

@echo offrem If current code was restarted, skip library loading partif "%_%" == "_" goto restartrem Copy current code and include any desired librarycopy /Y %0.bat+lib1.bat+libN.bat %0.full.batrem Set the restart flagset _=_rem Restart current code%0.full %*:restartrem Delete the restart flagset _=rem Place here the rest of the batch filerem . . . . .rem Always end with goto :eof, because the library functions will be loadedrem after this code!goto :eof


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:

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::::   Optionsset "_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 libset "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% Examplegoto:eof::End _IncludeLibraries::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::_main - Your code goes here::::::::::::::::::::::::::::::::::::::echo/Example code:call :Example "It works!"echo/____________________echo/Work folder: %CD%echo/echo/This file: %0echo/echo/Library paths: %_LibPaths%echo/____________________echo/Argument 1 = %1echo/Argument 2 = %2echo/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