FREE THOUGHT · FREE SOFTWARE · FREE WORLD

Home  »  Windows  »  Advanced Windows Batch File Scripting

by 27 comments

Create an AT job to run as system in Notepad++ IDE

Windows Batch Programming ExampleFirst off, this is a single windows .bat file that I have written to do advanced batch scripting the easy way, meaning it's mostly a series of functions you can call from the script or within other functions for extremely modular code. Before you get all bent out of shape by my choice of words ("easy, modular"), when I say this is advanced I mean for Windows .bat files, one of the worlds worst scripting languages, but it works on all windows versions so it's ideal for things like autorun, autoplay, custom startups, usb drives, etc.. If you are looking for information on how to use and program windows .bat files to do anything cool, this is the right place! I tried my best to mimic linux shell-scripting, so it's likely different than other batch files you have seen.

Contents [hide]

Batch File IDE and Script Source

Create an AT job to run as system in Notepad++ IDEMy favorite tool (and I've tried sooo many) for editing most Windows files and especially .bat files is the free and open-source Notepad++. Set that up and you will have a color-syntax-highlighted editor for Batch Scripting that works very very well.

The next thing to do is download the source code, which includes comments and formatting I had to remove for this online article. Then rename from .txt to .bat and open in your IDE/text-editor of choice.

Quick Batch File Example

This is a simple batch file named ping-check.bat that I use when rebooting remote servers. The reboot is issued from an SSH session and causes the server to go down and then come back up. When the server goes down the network goes down too so I fire this script up to continually ping the remote server until it responds, at which point I can ssh back in.

One of the first hacks for batch files is line 1, the PUSHD command cd's the scripts working environment to the directory of the script itself.

@ECHO OFF && PUSHD "%~dp0" && SETLOCAL

CALL :PINGCHECK "%~1"

nircmd.exe speak text "PING RECEIVED.  HOST BACK ONLINE" 7 60
ENDLOCAL && POPD && GOTO :EOF

:PINGCHECK
ECHO CHECKING %~1
ping.exe -n 1 %~1 -w 5000 | FIND /C "Reply from %~1" | FIND "1" >nul 2>&1
IF ERRORLEVEL 1 CALL :PINGCHECK "%~1" ELSE EXIT /B

Super-hero like even

Just added this as an after thought, moving the main example further down this page. This is an easier file to understand the scope of. It effectively creates SSH-encrypted SOCK5 tunnels that stay connected and auto-reconnect if the link goes down. I wanted to try and write a pure batch method to do that. I wrote this to run automatically from a USB key so that I could keep my tools with me portably. The thing of this script that is the most revolutionary is the method it uses to create auto-reconnecting SSH-encrypted SOCKS5 tunnels using the windows SYSTEM account to do it all in the background with plink.exe. The hack to run it as a system account is by using the built-in AT command to run interactively, which lets you interactively do whatever you want as the builtin NT AUTHORITY/SYSTEM account. The other part I am proud of with this is how lean I got the code, specifically how lean the function is that creates the at job to run every 5 minutes, while still doing connection-testing, all by parsing the cmd.exe processors builtin in DATE and TIME variables. Do a google search for "windows batch file date and time" and you will appreciate just how lean this sucker is.

Almost forgot, check out the ways to keep a plink.exe (putty.exe for cmd.exe) SOCKS5 tunnel hidden and safe and continuously connected to a remote server in minimal lines od code. This was a fun one to work on! Enjoy (and remember this is just the warm-up example to glance at).

@ECHO OFF && PUSHD "%~dp0" && SETLOCAL && SETLOCAL ENABLEDELAYEDEXPANSION && SETLOCAL ENABLEEXTENSIONS

SET _CRYPTDRIVE=%~d0
SET PATH=%_CRYPTDRIVE%PP;%_CRYPTDRIVE%PPbin;%PATH%
SET _PUTTYBIN=%_CRYPTDRIVE%PPPputty.exe

SET _PSERVER=solar.power.com
SET _PPORT=22
SET _PSESSION=newclean-tunnel

SET _ADMINUSER=admin
SET _RUNUSER=life



REM SAY CHECKING PLINK OUT LOUD
CALL :SPEAK "Checking Putty"
ECHO "CHECKING PUTTY"

REM
IF NOT EXIST "%_CRYPTDRIVE%" (
	CALL :SPEAK "Crypt Not Mounted"
	AT|FOR /F "tokens=1" %%i IN ('FIND /I "%~f0"') DO AT %%i /delete /yes >nul 2>&1
	pskill.exe -t putty >nul 2>&1
	pskill.exe -t thunderbird >nul 2>&1
	pskill.exe -t ThunderbirdPortable >nul 2>&1
	pskill.exe -t Firefox >nul 2>&1
	pskill.exe -t FirefoxPortable >nul 2>&1
	pskill.exe -t GC >nul 2>&1
	EXIT
)

REM CREATE AT JOB TO RUN THIS SCRIPT EVERY 5 MINUTES
CALL :CREATEATJOB

pslist putty >nul 2>&1
IF ERRORLEVEL 1 psexec.exe -i 0 -e -d -u %_RUNUSER% %_PUTTYBIN% -load %_PSESSION%


REM KILL MULTIPLE PSEXEC's
CALL :KILLDUPES "psexec.exe"

REM KILL MULTIPLE CMD.EXE's
CALL :KILLDUPES "cmd.exe"


REM REACHABLE SERVER CHECK
CALL :PINGCHECK %_PSERVER%

REM CHECK FOR INACTIVE PUTTY
CALL :PUTTYCHECK

REM CHECK PORT IS LISTENING (FOR SOCKISFIED TUNNEL)
CALL :PORTCHECK %_PPORT%

REM CALL :SPEAK "OK"
SLEEP 100 && ECHO "OK" && SLEEP 1 && ENDLOCAL && POPD && EXIT







REM =======================================================================================
REM =   SPEAK - Speak text
REM =======================================================================================
:SPEAK
nircmd.exe speak text "%~1" 5 60
ECHO "%~1"
EXIT /B




REM =======================================================================================
REM =   RESTARTPLINK - Sleeps for %1 number of seconds
REM =======================================================================================
:RESTARTPLINK
CALL :SPEAK "%~1 ReSTARTing Plink"
REM runas /savecred /user:admin "%_PUTTYBIN% -load %_PSESSION%"
psexec.exe -i 0 -e -d -u %_RUNUSER% %_PUTTYBIN% -load %_PSESSION%
EXIT
EXIT /B




REM =======================================================================================
REM =   PORTCHECK - Check that Port is being used (for tunnels)
REM =======================================================================================
:PORTCHECK
netstat.exe -n -v -a -p TCP | FIND "ESTABLISHED" | FIND ":%~1" >nul 2>&1
IF ERRORLEVEL 1 CALL :RESTARTPLINK "PORT CHECK FAILED"
EXIT /B




REM =======================================================================================
REM =   INACTIVEPUTTYCHECK - Check for inactive putty windows
REM =======================================================================================
:PUTTYCHECK
tasklist.exe /V /NH /FI "WINDOWTITLE eq PuTTY (inactive)" 2>nul|FIND "INFO: " >nul 2>&1
IF ERRORLEVEL 1 taskkill.exe /T /F /FI "WINDOWTITLE eq PuTTY (inactive)" >nul 2>&1

:: MAKE SURE ONLY 1 putty is running that is connected to the remote server
netstat.exe -n -a -o -p TCP | FIND ":%_PPORT%" | FIND /C ":%_PPORT%" | FIND "1" >nul 2>&1
IF ERRORLEVEL 1 (
  tasklist.exe /V /FO TABLE /NH /FI "IMAGENAME eq putty.exe" 2>nul | FIND /C "Running" | FIND "1" >nul 2>&1
  IF ERRORLEVEL 1 (
    REM kill all running puttys (owned by system)
    FOR /F "usebackq tokens=2 skip=2" %%p IN (`tasklist.exe /V /FO TABLE /NH /FI "IMAGENAME eq putty.exe"`) DO taskkill.exe /F /PID %%p /T >nul 2>&1
    CALL :RESTARTPLINK "EXTRA PUTTY FOUND"
  )
)
EXIT /B







REM =======================================================================================
REM =   PINGCHECK - PING address to make sure it is reachable
REM =======================================================================================
:PINGCHECK
PING %~1 -n 1 -w 5000 | FIND "TTL=" >nul 2>&1
IF ERRORLEVEL 1 (
  PING google.com -n 1 -w 500 | FIND "TTL=" >nul 2>&1
  IF ERRORLEVEL 1 ( CALL :SPEAK "CHECK INTERNET CONNECTION" && SLEEP 60 )

  PING google.com -n 1 -w 5000 | FIND "TTL=" >nul 2>&1
  IF ERRORLEVEL 1 ( CALL :SPEAK "CHECK INTERNET CONNECTION" && SLEEP 60 )

  PING google.com -n 1 -w 5000 | FIND "TTL=" >nul 2>&1
  IF ERRORLEVEL 1 (
    CALL :SPEAK "KILL SOCKS PROGRAMS"
	SLEEP 100
	pskill.exe -t putty >nul 2>&1
	pskill.exe -t thunderbird >nul 2>&1
	pskill.exe -t ThunderbirdPortable >nul 2>&1
  )
)
EXIT /B





REM =======================================================================================
REM =   KILLDUPES - kills duplicate processes, except for the one with lowest pid
REM =======================================================================================
:KILLDUPES
REM Check that more than 1 process is running
tasklist.exe /V /NH /FI "IMAGENAME eq %~1" /FI "USERNAME eq SYSTEM" 2>nul | FIND /C "K Running" | FIND "1" >nul 2>&1
IF NOT ERRORLEVEL 1 EXIT /B

REM Create Filename in current dir (of this script)
SET _T=%TIME: =0%&&SET _T=!_T::=-!&&SET _T=%~dp0%!_T:~0,-2!log

REM Create the file in the same dir as this script named for date and sorted by PID
tasklist.exe /V /NH /FI "IMAGENAME eq %~1" /FI "USERNAME eq SYSTEM" 2>nul | SORT /+29 > "%_T%"

REM Check that the file was created or exit
IF NOT EXIST "%_T%" ( CALL :SPEAK "FILE CREATION FAILED" && EXIT /B )

REM kill all the processes found except for 1, do not kill the process with the lowest pid number
FOR /F "tokens=2 skip=2" %%p IN (%_T%) DO taskkill.exe /F /PID %%p /T

REM erase the file
REM ERASE /Q "%_T%" >nul 2>&1

REM check that the file was erased
REM IF EXIST "%_T%" ( CALL :SPEAK "ERASE FILE FAILED" && EXIT /B )

EXIT /B






REM =======================================================================================
REM =   CREATEATJOB - runs job (START this file) every 5 minutes
REM =======================================================================================
:CREATEATJOB
:: delete all putty AT jobs
AT | FIND /C "%~f0" | FIND "1" >nul 2>&1
IF ERRORLEVEL 1 ( AT|FOR /F "tokens=1" %%i IN ('FIND /I "%~f0"') DO AT %%i /delete /yes >nul 2>&1 )
SET /A H=!TIME:~0,2!&& SET M=!TIME:~3,2!
SET Y=%H%:%M%&& SET /A M+=5
IF !M! GEQ 61 ( SET /A H+=1&&SET /A M-=61 )
IF !H! GEQ 24 SET /A H-=24
SET M=0!M!&& SET H=0!H!
:: create AT job
AT %H:~-2%:%M:~-2% /INTERACTIVE %ComSpec% /E:ON /D /Q /C START /B /MIN %ComSpec% /E:ON /D /Q /C "%~f0" >nul
EXIT /B

Advanced Batch File

This is the main batch file example which you can download here. Other than some minor changes this is the actual script I use at work when I logon to my PC. The first thing it does is mount an encrypted TrueCrypt Drive where all of my files and settings are located. It also starts a putty session named "1" that I configured to start a few encrypted tunnels and socks proxies so that my email Thunderbird and Website IDE Dreamweaver and other network apps can communicate 100% encrypted and my real location becomes hidden (thanks socks!).

I might come back later and add comments if I get any kind of response for this article, and because it's such a unique and low-traffic topic, I will try to answer any questions added with the comment form.

Starting the Script

The first line is of my own design and is perhaps the coolest hack in the script. I use this 1 line to start pretty much all of my .bat files.

@ECHO OFF&& SETLOCAL&& PUSHD "%~dp0"&& SETLOCAL ENABLEDELAYEDEXPANSION&& SETLOCAL ENABLEEXTENSIONS&& SET V=5&& IF NOT "!V!"=="5" (ECHO DelayedExpansion Failed&& GOTO :EOF)

SCRIPT VARIABLES

These are all local to this script thanks to the SETLOCAL above, so they won't exist outside the scripts execution environment.

REM ** Various vars for output used by functions
SET P1=^^^>^^^>^^^>
SET P2=++
SET P3=::
SET L1=+==============================================================================================================+
SET L2=+--------------------------------------------------------------------------------------------------------------+


REM ** administrator username, unless changed for more security, its Administrator
SET ADMINUSER=admin

REM ** runuser is the username you use when running this script
SET RUNUSER=bill

REM ** Custom COMSPEC for running cmd.exe
SET _SCOM=%COMSPEC% /E:ON /F:ON /D /Q /T:0C /C

REM ** Custom START command
SET _START=START /WAIT /MIN /B %_SCOM%

MAIN PROGRAM EXECUTION

This is where the main code starts, note how small it is thanks to the use of functions (labels/call/goto). Read the comments in this area (start with :: or REM ) to see the extent of this script. The gold is in the functions.

:: Only allow certain users to run this script or die (prevents global STARTup or service running it)
CALL :CHECKUSERVALID %RUNUSER% %ADMINUSER%

:: Mount the truecrypt container
CALL :CRYPTMOUNT "L" "%SYSTEMDRIVE%CRYPTLEONARDO" "%SYSTEMDRIVE%CRYPTLEONARDO_KEY"

:: Start Mozilla Firefox
CALL :RUNONE "C:Program FilesMozilla Firefoxfirefox.exe"

:: Start Thunderbird Portable
CALL :RUNONE "L:PPPputty.exe" "/MIN" -load 1

:: Start Thunderbird Portable
CALL :RUNONE "L:PTBThunderbirdPortable.exe" "/MIN"

:: Start Adobe Dreamweaver CS4
CALL :RUNONE "C:Program FilesAdobeAdobe Dreamweaver CS4Dreamweaver.exe" "/MIN"

:: Start LightScreen Portable
CALL :RUNONE "L:PLPLightscreenPortable.exe" /B /B

:: Start Google Chrome Portable ( GREAT to use for pandora/last.fm as its so low mem )
CALL :RUNONE "L:PGCGC.exe" "/NORMAL"

:: Start Adobe Photoshop CS4
CALL :RUNONE "%ProgramFiles%AdobeAdobe Photoshop CS4Photoshop.exe" "/MAX"

Exit Script

This is the last line executed in the Main, it forces the script to exit cleanly at this point, otherwise the functions below would all get executed. This is what allows the use of all the functions below. I end all my scripts MAIN with this.

REM ** EXIT Script
CALL :MDYE "EOF" && POPD && ENDLOCAL && GOTO :EOF

SCRIPT FUNCTIONS

Now then, onto the MEAT of the script, all the functions. These functions are designed for global use in other batch files, so that the only modification when you make a new batch is the above variables and main execution.. If you know much about batch files you will realize that creating these functions was a very painful process in some cases.. I freakin hate windows! Anyway, enjoy!

CRYPTMOUNT - mounts a truecrypt container and returns to CALLer. On fail, quit

REM
REM     CALL :CRYPTMOUNT "%LEONARDO%" "%LEONARDO_FILE%" "%LEONARDO_KEY%"
REM     CALL :CRYPTMOUNT "L" "%SYSTEMDRIVE%CRYPTLEONARDO" "%SYSTEMDRIVE%CRYPTLEONARDO_KEY"
REM
REM :: print the settings
REM :: CALL :MP 3 "DRIVE: %DRIVE%"&&CALL :MP 3 " FILE: %FILE%"&&CALL :MP 3 "  KEY: %KEY%"&&CALL :MP 3 "  VOL: %VOL%"
:CRYPTMOUNT
SET DRIVE=%~1&& SET FILE=%~2&& SET KEY=%~3&& SET VOL=!FILE:~0,3!
CALL :MP 1 "Mounting TrueCrypt on %DRIVE% from %FILE%"

:: Check for Truecrypt or die
CALL :EXISTORQUIT "%ProgramFiles%TrueCryptTrueCrypt.exe" && CALL :EXISTORQUIT "%FILE%" && CALL :EXISTORQUIT "%KEY%"

:: checks that MOUNTVOL works and the drive containing the truecrypt container file is present or dies
MOUNTVOL %VOL% /L 2>NUL | FIND "\?Volume{" >NUL 2>&1
IF ERRORLEVEL 1 CALL :MDYE "%VOL% NOT FOUND"

REM ** Converts G: to its \?Volume{234234} equivalent for greater portability
FOR /F %%i IN ('MOUNTVOL %VOL% /L') DO @SET VOL=%%i%FILE:~3%

:: IF the drive is already mounted then continue, otherwise try to mount
MOUNTVOL %DRIVE%: /L >NUL 2>&1
IF NOT ERRORLEVEL 1 (
  CALL :MP 2 "%DRIVE% ALREADY MOUNTED" && EXIT /B
) ELSE (
  START "Mounting TrueCrypt" /D"%ProgramFiles%TrueCrypt" /MIN /B TrueCrypt.exe /c n /b /q background /h n /k %KEY% /l %DRIVE% /p /v %VOL% && SLEEP 10
)

:: try again in case of bad password and accidental keypress
MOUNTVOL %DRIVE%: /L >NUL 2>&1
IF ERRORLEVEL 1 (START "Mounting TrueCrypt" /D"%ProgramFiles%TrueCrypt" /MIN /B TrueCrypt.exe /c n /b /q background /h n /k %KEY% /l %DRIVE% /p /v %VOL% && SLEEP 10)

:: IF it still doesnt exist then quit
MOUNTVOL %DRIVE%: /L >NUL 2>&1
IF ERRORLEVEL 1 CALL :MDYE "Failed to mount %FILE% on %DRIVE%"

CALL :MF && ENDLOCAL && EXIT /B
EXIT /B

RUNONE - Starts one instance of executable after verifying it exists and is not already running.

REM     %~1 is location of executatable
REM     %~2 is optional (unless %~3 is used) START parameters
REM     %~3 is optional parameters for executable
REM
REM     CALL :RUNONE "L:PLPLightscreenPortable.exe" "/MAX" "/HIDE"
:RUNONE
SETLOCAL
CALL :MP 1 "Starting %~n1"

:: SLEEP FOR NICENESS, LOCAL VARS _P2 and _P3
SLEEP 2 && SETLOCAL

SET P=%~1
ECHO %P%|FIND " " >NUL 2>&1
IF NOT ERRORLEVEL 1 ( PUSHD "%~dp1" && SET P=%~nx1 )

:: SET _P2 TO DEFAULT TO "/MIN" IF EMPTY
SET _P2=/MIN
IF NOT " %~2" == " " SET _P2=%~2
IF NOT " %~3" == " " SET _P3=%~3
IF NOT " %~4" == " " SET _P4=%~4

:: CHECK THAT EXECUTABLE EXISTS
CALL :EXISTORQUIT "%~1"

REM ECHO START %_P2% /D"%~dp1" %P% %_P3% %_P4%&& PAUSE&&
:: CHECK FOR EXISTING PROCESSNAME ( %~n1 is file name without ext, %~nx1 is the file name and extension. )
pslist.exe /e %~n1 >NUL 2>&1
IF ERRORLEVEL 1 (START %_P2% /D"%~dp1" %P% %_P3% %_P4% ) ELSE (CALL :MP 2 "%~n1 already running!" )

ENDLOCAL && EXIT /B

ADMINRUNONE - Runs %1 with admin rights IF neccessary

:ADMINRUNONE
CALL :MP 3 "Exec %~1 as %ADMINUSER%"

:: Check that file exists
CALL :EXISTORQUIT "%~1"

:: test for rights to the task scheduler
:: %SYSTEMDRIVE%WINDOWSsystem32cmd.exe /E:ON /D /Q /T:0C /C START /WAIT /MIN /B %SYSTEMDRIVE%WINDOWSsystem32cmd.exe /E:ON /D /Q /T:0C /C %~1
AT >NUL 2>&1
IF ERRORLEVEL 1 (
  RUNAS /noprofile /user:%USERDOMAIN%%ADMINUSER% "%~1"
) ELSE (
  %COMSPEC% /E:ON /D /Q /T:0C /C "%~1"
)
SLEEP 2 && CALL :MF && EXIT /B

CHECKUSERVALID - checks that defined username equals %ADMINUSER% or %RUNUSER%, then returns to CALLer

:CHECKUSERVALID
:: EXIT IF USERNAME IS NOT DEFINED, CATCHES SYSTEM ACCOUNTS TRYING TO RUN WHEN IN GLOBAL STARTUP
IF NOT DEFINED USERNAME EXIT

SETLOCAL
SET UP=no
SET _P1= %~1
SET _P2= %~2
IF NOT "%_P1%" == " " ( IF /I "%~1" == "%USERNAME%" SET UP=yes)
IF NOT "%_P1%" == " " ( IF /I "%~1" == "%USERNAME%" SET UP=yes)
IF NOT "%_P1%" == " " ( IF /I "%~1" == "%USERNAME%" SET UP=yes)
IF /I "bill" == "%USERNAME%" SET UP=yes
IF /I "newbill" == "%USERNAME%" SET UP=yes
IF /I "max" == "%USERNAME%" SET UP=yes
IF /I NOT "%UP%" == "yes" EXIT
ENDLOCAL
EXIT /B

SETPROMPT - sets prompt, then returns to CALLer

REM =   [user@MACHINE] [C:DRPEPPERSCRIPTS]
REM =   > REG /?
:SETPROMPT
set PROMPT=$_[%USERNAME%@%USERDOMAIN%]$S[$P]$_$M$G && EXIT /B

BEEP - beeps once, then returns to CALLer

The character after the echo is the actual BEL char, so unless you have my source file, you will need to copy a literal BEL char here to make it beep.

:BEEP
@ECHO # && EXIT /B

MSETCOLOR - SET colors for screen, then returns to CALLer

REM
REM     0 = Black       8 = Gray
REM     1 = Blue        9 = Light Blue
REM     2 = Green       A = Light Green
REM     3 = Aqua        B = Light Aqua
REM     4 = Red         C = Light Red
REM     5 = Purple      D = Light Purple
REM     6 = Yellow      E = Light Yellow
REM     7 = White       F = Bright White
REM
:MSETCOLOR
COLOR %~1 && EXIT /B

MSETCONSOLE - sets the cols and lines of current screen buffer, then returns to CALLer

:MSETCONSOLE
MODE CON COLS=%~1 LINES=%~2 && EXIT /B

PARAMTEST - tests params, then returns to CALLer

:PARAMTEST
ECHO. && CALL :MP 1 "PARAMTEST CALLED WITH: %*" && ECHO %L1%
SET _P= %~1
IF NOT "%_P%" == " " ( ECHO %%1          = %1 && ECHO %%~f1        = %~f1 && ECHO %%~d1        = %~d1 && ECHO %%~p1        = %~p1
  ECHO %%~n1        = %~n1 && ECHO %%~x1        = %~x1 && ECHO %%~s1        = %~s1 && ECHO %%~dp1       = %~dp1
  ECHO %%~nx1       = %~nx1 && ECHO %%~$PATH:1   = %~$PATH:1 && ECHO %%~dp$PATH:1 = %~dp$PATH:1 && ECHO %L1% )
SET _P= %~2
IF NOT "%_P%" == " " ( ECHO %%2          = %2 && ECHO %%~f2        = %~f2 && ECHO %%~d2        = %~d2 && ECHO %%~p2        = %~p2
  ECHO %%~n2        = %~n2 && ECHO %%~x2        = %~x2 && ECHO %%~s2        = %~s2 && ECHO %%~dp2       = %~dp2
  ECHO %%~nx2       = %~nx2 && ECHO %%~$PATH:2   = %~$PATH:2 && ECHO %%~dp$PATH:2 = %~dp$PATH:2 && ECHO %L1% )
SET _P= %~3
IF NOT "%_P%" == " " ( ECHO %%3          = %3 && ECHO %%~f3        = %~f3 && ECHO %%~d3        = %~d3 && ECHO %%~p3        = %~p3
  ECHO %%~n3        = %~n3 && ECHO %%~x3        = %~x3 && ECHO %%~s3        = %~s3 && ECHO %%~dp3       = %~dp3
  ECHO %%~nx3       = %~nx3 && ECHO %%~$PATH:3   = %~$PATH:3 && ECHO %%~dp$PATH:3 = %~dp$PATH:3 && ECHO %L1% )
SET _P= %~4
IF NOT "%_P%" == " " ( ECHO %%4          = %4 && ECHO %%~f4        = %~f4 && ECHO %%~d4        = %~d4 && ECHO %%~p4        = %~p4
  ECHO %%~n4        = %~n4 && ECHO %%~x4        = %~x4 && ECHO %%~s4        = %~s4 && ECHO %%~dp4       = %~dp4
  ECHO %%~nx4       = %~nx4 && ECHO %%~$PATH:4   = %~$PATH:4 && ECHO %%~dp$PATH:4 = %~dp$PATH:4 && ECHO %L1% )
SET _P= %~5
IF NOT "%_P%" == " " ( ECHO %%5          = %5 && ECHO %%~f5        = %~f5 && ECHO %%~d5        = %~d5 && ECHO %%~p5        = %~p5
  ECHO %%~n5        = %~n5 && ECHO %%~x5        = %~x5 && ECHO %%~s5        = %~s5 && ECHO %%~dp5       = %~dp5
  ECHO %%~nx5       = %~nx5 && ECHO %%~$PATH:5   = %~$PATH:5 && ECHO %%~dp$PATH:5 = %~dp$PATH:5 && ECHO %L1% )
SET _P= %~6
IF NOT "%_P%" == " " ( ECHO %%6          = %6 && ECHO %%~f6        = %~f6 && ECHO %%~d6        = %~d6 && ECHO %%~p6        = %~p6
  ECHO %%~n6        = %~n6 && ECHO %%~x6        = %~x6 && ECHO %%~s6        = %~s6 && ECHO %%~dp6       = %~dp6
  ECHO %%~nx6       = %~nx6 && ECHO %%~$PATH:6   = %~$PATH:6 && ECHO %%~dp$PATH:6 = %~dp$PATH:6 && ECHO %L1% )
SET _P= %~7
IF NOT "%_P%" == " " ( ECHO %%7          = %7 && ECHO %%~f7        = %~f7 && ECHO %%~d7        = %~d7 && ECHO %%~p7        = %~p7
  ECHO %%~n7        = %~n7 && ECHO %%~x7        = %~x7 && ECHO %%~s7        = %~s7 && ECHO %%~dp7       = %~dp7
  ECHO %%~nx7       = %~nx7 && ECHO %%~$PATH:7   = %~$PATH:7 && ECHO %%~dp$PATH:7 = %~dp$PATH:7 && ECHO %L1% )
SLEEP 3
CALL :MF
EXIT /B

PARAMTESTHELP - show params help, then returns to CALLer

:PARAMTESTHELP
ECHO %%~1 Expands %%1 and removes any surrounding quotation marks
ECHO %%~f1 Expands %%1 to a fully qualified path name.
ECHO %%~d1 Expands %%1 to a drive letter.
ECHO %%~p1 Expands %%1 to a path.
ECHO %%~n1 Expands %%1 to a file name.
ECHO %%~x1 Expands %%1 to a file extension.
ECHO %%~s1 Expanded path contains short names only.
ECHO %%~a1 Expands %%1 to file attributes.
ECHO %%~t1 Expands %%1 to date and time of file.
ECHO %%~z1 Expands %%1 to size of file.
ECHO %%~dp1 Expands %%1 to a drive letter and path.
ECHO %%~nx1 Expands %%1 to a file name and extension.
ECHO %%~ftza1 Expands %%1 to a dir-like output line.
ECHO %%~$PATH:1 Searches the dirs in PATH expanding %%1 to fully qualified name of first found. If var name isn't defined or the files not found, expands to empty string.
ECHO %%~dp$PATH:1 Searches the directories listed in the PATH environment variable for %%1 and expands to the drive letter and path of the first one found.
CALL :MF
EXIT /B

EXAMINEFILE - FINDs useful strings in file, then returns to CALLer

:EXAMINEFILE
CALL :MP 1 "Examine File %~1"
CALL :EXISTORQUIT "%~1"
STRINGS "%~1" | FINDSTR /R /C:"[A-Z][A-Z]="
CALL :MF
EXIT /B

ADMINSHELL - sets prompt, then returns to CALLer

:ADMINSHELL
CALL :MP 1 "Creating Admin Shell"
CALL :EXISTORQUIT "%SYSTEMROOT%system32runas.exe"
START %SYSTEMROOT%system32runas.exe /profile /savecred /user:%ADMINUSER% "%COMSPEC% /T:0C /E:ON /F:ON /K cmd.exe /K cd C:CRYPTBIN"
CALL :MF
EXIT /B

EXISTORQUIT - checks %~1 exists, IF it does returns to CALLer, otherwise, quit

:EXISTORQUIT
:: CALL :MP 1 "Checking for %~1"
IF NOT EXIST "%~1" CALL :MDYE "%~1 NOT FOUND"
EXIT /B

RR - IF file %1 EXISTs then :MT "Removing %1" then :MF, then ( or IF %1 not EXISTs) returns to CALLer

:RR
CALL :MP 1 "Removing %~1"
IF EXIST "%~1" ERASE /q "%~1"
CALL :MF && EXIT /B

LOCKDOWN - locks workstation, then returns to CALLer (pointless)

:LOCKDOWN
RUNDLL32 USER32.DLL,LockWorkStation && EXIT /B

SHUTDOWNIN - initiates shutdown, then returns to CALLer (pointless)

REM shutdown /a aborts
:SHUTDOWNIN
SHUTDOWN -r -t "%~1" && EXIT /B

LISTSERVICES - lists services, then returns to CALLer

:LISTSERVICES
SC query state= all type= all | FOR /F "tokens=2" %%i IN ('FIND /I "SERVICE_NAME"') DO @ECHO %%i
SC query | FOR /F "tokens=2" %%i IN ('FIND /I "SERVICE_NAME"') DO @ECHO %%i
EXIT /B

TASKS - Advanced Tasklisting

:TASKS
SET _P=%~1
SET _PP= %~1
IF "%_PP%" == " " EXIT /B

REM SORTABLES
IF /I "%_P%" == "pid" ( tasklist.exe /V /NH | SORT /+29 && EXIT /B )
IF /I "%_P%" == "size" ( tasklist.exe /V /NH | SORT /+59 && EXIT /B )
IF /I "%_P%" == "user" ( tasklist.exe /V /NH | SORT /+89 && EXIT /B )
IF /I "%_P%" == "time" ( tasklist.exe /V /NH | SORT /+138 && EXIT /B )
IF /I "%_P%" == "window" ( tasklist.exe /V /NH | SORT /+152 && EXIT /B )

REM FILTERS
IF /I "%_P%" == "image" ( tasklist.exe /V /NH /FI "IMAGENAME eq %~2" && EXIT /B )
IF /I "%_P%" == "username" ( tasklist.exe /V /NH /FI "USERNAME eq %~2" && EXIT /B )
IF /I "%_P%" == "running" ( tasklist.exe /V /NH /FI "STATUS eq Running" && EXIT /B )
IF /I "%_P%" == "status" ( tasklist.exe /V /NH /FI "STATUS eq %~2" && EXIT /B )
CALL :MF
EXIT /B

SPEAK - Speak text

:SPEAK
REM ECHO "%~1"
nircmd.exe speak text "%~1" 5 60 && EXIT /B

MF - SLEEPs for 1 second, then prints out completed message, followed by 2 blank lines, then returns to CALLer

:MF
SLEEP 1 && ECHO  [COMPLETED] && ECHO. && ECHO. && EXIT /B

MM - prints blank line, L1, changes title of the interpreter window to %~1, prints >>> %~1..., L2, blank line, then returns to CALLer

:MM
SLEEP 1 && ECHO. && ECHO %L1% && title +++ %~1... && ECHO %P1% %~1... && ECHO %L2% && ECHO. && EXIT /B

MT - prints blank line, L1, changes title of the interpreter window to %~1, prints >>> %~1..., L2, blank line, then returns to CALLer

:MT
CALL :MM "%~1" && CALL :SPEAK "%~1" && EXIT /B

MP - Print Output, then returns to CALLer

:MP
IF "%~1" == "1" ECHO %P1% %~2 && EXIT /B
IF "%~1" == "2" ECHO %P2% %~2 && ECHO. && EXIT /B
IF "%~1" == "3" ECHO %P3% %~2 && EXIT /B
EXIT /B

MP3 - ECHO %~1, speak %~1 with nircmd.exe, then returns to CALLer

:MP3
CALL :MP 1 "%~1" && CALL :SPEAK "%~1" && EXIT /B

MDYE - exit script with message %~1, then returns to CALLer

:MDYE
SETLOCAL
SET _M= %~1
IF NOT "%_M%" == " " SET _M=REASON: %~1
CALL :MP 1 "EXITING SCRIPT...  %_M%" && ECHO. && ECHO.
ENDLOCAL && EXIT /B

MKILL - exit cmd processor with message %~1

:MKILL
SETLOCAL
SET _M= %~1
IF NOT "%_M%" == " " SET _M=REASON: %~1
ECHO. && ECHO. && CALL :MP 1 "EXITING CMD WINDOW IN 3 SECONDS...  %_M%" && ECHO. && ECHO. && SLEEP 3
ENDLOCAL && EXIT && EXIT && EXIT

EOF: Thoughts

So what did you think? I have around 20 batch scripts that utilize these and other functions to do all sorts of cool things. One takes a screenshot of my desktop every 10 minutes and saves it for a real-cool archive of my activity. Another lets me edit a boot.ini file with 1 command.. And another runs when I insert a USB drive to automatically mount a truecrypt volume and create SSH tunnels in the background by using Plink, AT, and the runas.exe command.

If you want to program, please use linux... If you need to write a Windows batch file, I hope this helps.

Tags

June 5th, 2013

Comments Welcome

  • Dylan

    I'd sure like to know how you did the screenshot every 10 minutes script. I've been trying to figure that one out all week, can you give me a clue?

  • skoda

    I appreciate the effort you have put in presenting a very useful article on writing better batch scripts.

    Do you know if there is a technique to source (like in unix/linux shells) one batch script in another. I want to put all common functions in one script and then source it in other scripts. These other scripts will call some functions from the sourced script where ever they need them.

  • AskApache

    @skoda ~

    Originally that was my thought as well and I wanted to do exactly that. The answer is yes it is possible, I am able to get it to work the way you think that it would. But the reality is that it (batch) is extremely poor programming by microsoft, they never intended it to be used by humans I guess..

    I had to do a couple hours of trial and error before I finally figured it out.. Actually, figuring out how to do it without looping is similar to debugging mod_rewrite loops, things can really get out of control fast and seemingly without reason when dealing with batch files.

    @Dylan ~

    How about a full-fledged working solution? Please post back if you make any improvements...

  • judgedredd

    Hi,

    I have been searching high and low for a version of this script (which searches all drives for jpg or jpeg files to delete) that deals with finding a file and doing an action if it finds it and doing another action if it does not find it. The script I found that finds the jpg files and finds the drives by using the mountvol code is this:

    @echo off
    for /F %%a in ('mountvol ^| find ":"') do (
    dir %%a 1>nul 2>nul
    if not ErrorLevel 1 (
    del /s /f %%a*.jpg
    del /s /f %%a*.jpeg
    )
    )

    What I want is a variation of this code to do this:

    @echo off
     
    for %%a in (C D E F G H I J K L M N O P Q R S T U V W X Y Z) do if exist %%a:pagefile.sys start VAUTORUN.EXE
     
    for %%a in (C D E F G H I J K L M N O P Q R S T U V W X Y Z) do if not ErrorLevel 1(
     %%a:pagefile.sys CALL AUTORUN.INF
    )
    EXIT
    EXIT

    So you see that in the second example all the drives are written out whereas in the first example they are not. Any ideas on how to incorporate the mountvol code into the second example so that all the drive letters don't have to be written out like inthe first example?

  • Jesse~~

    I like your unique scripting method, especially you check for delayed expansion. This could truly help eliminate errors. I have been using this method to nest subroutines and call Multiple subroutines. It is very handy because for the most part I can add the same call modules in every script and call them as needed. For example, sleep.exe is not present on most systems, so the delay you have won't work on every system, and using ping will cause alarms if a good firewall is used, so I call this in most of my scripts and adjust the loops as needed for a timed delay.

    :Sleep
    ::~Note: This can create a different delay time if echo is on, creates a much greater delay.~::
    set /a cnt=%cnt%+1
    if %cnt%==10000 goto :EOF
    Goto Sleep

    I hope this helps someone!

  • pasindu

    how to program a batch file to start firefox every 5 min???

    • AskApache
      @ECHO OFF&& SETLOCAL&& PUSHD "%~dp0"&& SETLOCAL ENABLEDELAYEDEXPANSION&& SETLOCAL ENABLEEXTENSIONS&& SET V=5&& IF NOT "!V!"=="5" (ECHO DelayedExpansion Failed&& GOTO :EOF)
       
      REM ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
      REM ++                                                                                                                                                                                                ++
      REM ++   SCRIPT LOCAL VARIABLES                                                                                                                                                                       ++
      REM ++                                                                                                                                                                                                ++
      REM ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       
      SET _FIREFOXBIN=C:Program FilesMozilla Firefoxfirefox.exe
      SET PATH=%ProgramFiles%;%PATH%
      SET _PLOG=L:PPPatlog.log
       
      REM ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
      REM ++                                                                                                                                                                                                ++
      REM ++   MAIN PROGRAM EXECUTION                                                                                                                                                                       ++
      REM ++                                                                                                                                                                                                ++
      REM ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       
      REM CREATE AT JOB TO RUN THIS SCRIPT EVERY 5 MINUTES
      CALL :CREATEATJOB
       
      CALL :STARTFIREFOX
       
      :: CHECK ONLY 1 FIREFOX IS RUNNING
      CALL :FIREFOXCHECKMULTI
       
      POPD && ENDLOCAL && EXIT && EXIT
      GOTO :EOF
       
      REM ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
      REM ++                                                                                                                                                                                                ++
      REM ++   SCRIPT FUNCTIONS                                                                                                                                                                             ++
      REM ++                                                                                                                                                                                                ++
      REM ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       
      REM =========================================================================================================================================================================
      REM =   STARTFIREFOX
      REM =========================================================================================================================================================================
      :STARTFIREFOX
      ECHO.&& ECHO STARTING FIREFOX
      CALL :KILLDUPES "firefox.exe"
      START "firefox" /HIGH /MIN  "%_FIREFOXBIN%"
      IF ERRORLEVEL 1 ( CALL :SPEAK "FAILED. START FIREFOX" ) ELSE ( ECHO OK )
      EXIT /B
       
      REM =======================================================================================
      REM =   CREATEATJOB - runs job (START this file) every 5 minutes
      REM =======================================================================================
      :CREATEATJOB
      ECHO.&& ECHO CREATE AT JOB
      AT | FOR /F "tokens=1" %%i IN ('FIND /I "%~f0"') DO AT %%i /delete /yes >NUL 2>&1
      SET /A H=!TIME:~0,2!&& SET M=!TIME:~3,2!
      SET Y=%H%:%M%&& SET /A M+=5
      IF !M! GEQ 60 ( SET /A H+=1&&SET /A M-=60 )
      IF !H! GEQ 24 SET /A H-=24
      SET M=0!M!&& SET H=0!H!
      AT %H:~-2%:%M:~-2% /INTERACTIVE %ComSpec% /E:ON /D /Q /C START /MIN %ComSpec% /E:ON /D /Q /C "%~f0" >NUL 2>&1
      ECHO OK
      EXIT /B
       
      REM =======================================================================================
      REM =   KILLDUPES - kills duplicate processes, except for the one with lowest pid
      REM =======================================================================================
      :KILLDUPES
      ECHO.&& ECHO KILLING DUPLICATE FIREFOXS
      REM Check that more than 1 process is running
      ::tasklist.exe /V /NH /FI "IMAGENAME eq %~1" /FI "USERNAME eq SYSTEM" 2>nul | FIND /C "K Running" | FIND "1" >nul 2>&1
      tasklist.exe /V /NH /FI "IMAGENAME eq %~1" 2>nul | FIND /C "K Running" | FIND "1" >nul 2>&1
      IF NOT ERRORLEVEL 1 EXIT /B
       
      REM Create Filename in current dir (of this script)
      SET _CMDS=%TEMP%killdupes.log
       
      REM Create the file in the same dir as this script named for date and sorted by PID
      tasklist.exe /V /NH /FI "IMAGENAME eq %~1" 2>nul | SORT /+29 > "%_CMDS%"
       
      REM Check that the file was created or exit
      IF NOT EXIST "%_CMDS%" ( CALL :SPEAK "FILE CREATION FAILED" && EXIT /B )
       
      REM kill all the processes found except for 1, do not kill the process with the lowest pid number
      FOR /F "usebackq tokens=2 skip=2" %%p IN (`type "%_CMDS%"`) DO taskkill.exe /F /PID %%p /T >nul 2>&1
       
      REM erase the file
      ERASE /Q "%_CMDS%" >nul 2>&1
       
      REM check that the file was erased
      IF EXIST "%_CMDS%" ( CALL :SPEAK "ERASE FILE FAILED" && EXIT /B )
       
      EXIT /B
       
      REM =======================================================================================
      REM =   SPEAK - Speak text
      REM =======================================================================================
      :SPEAK
      ECHO %~1
      EXIT /B
  • John

    Hi - Can someone help me. Im trying to create a batch file please that would do the following:

    1. check to see if application is running
    2. if its open then close running app
    3. then run installation.exe
    4. then relaunch application

    I have some of it already mentioned below. But im missing some of the other commands on the script

    So in other words something like this. please fill what im missing.

    @echo off
    Var opened = false
    If (notepad++ is opened)
    tskill notepad++ > NUL
    opened = true
    c:notenpp.6.2.Installer.exe /S
    if (opened = true)
    start "" "C:Program Files (x86)Notepad++notepad++.exe"

    Please HELP!!!!

  • jack

    please help me make this shorter and easier

    @echo off
    color 09
     
    echo loading 1 %
    ping localhost -n 1 >nul
    cls
    echo loading 2 %
    ping localhost -n 1 >nul
    cls
    echo loading 3 %
    ping localhost -n 1 >nul
    ...
    echo loading 100 %
    ping localhost -n 2 >nul
  • AskApache

    @John

    Normally I'd say GRTFM, but since this is windows batch, hey what the heck. Here ya go.

    @ECHO OFF
     
    SET NPEXE=C:Program Files (x86)Notepad++notepad++.exe
    SET NPIMG=notepad++.exe
    SET NPINSTALLER=C:Program Files (x86)Notepad++notenpp.6.2.Installer.exe /S
     
    tasklist.exe /V /FO TABLE /NH /FI "IMAGENAME eq %NPIMG%" 2>NUL | FIND "%NPIMG% " >NUL 2>&1
    IF ERRORLEVEL 1 (
      ECHO %NPIMG% not running, starting
      START /D"C:Program Files (x86)Notepad++" %NPIMG%
    ) ELSE (
      ECHO %NPIMG% already running, killing
      tskill %NPIMG%
      ECHO Starting installer
      START /D"C:Program Files (x86)Notepad++" %NPINSTALLER%
      SLEEP 5
      ECHO Starting notepad++
      START /D"C:Program Files (x86)Notepad++" %NPIMG%
    )
  • Sheila

    What I need I don't believe is terribly complicated, but I am normally a unix user and not particurlarly adept in windows, but I have a need to capture information in a text file on a windows 2003 server and then email it.

    I need the date format to be dd/MONTH/yyyy - MONTH = 3 char in uppercase. The date will always be the current one.

    I need to incorporate this into a command to be run as a scheduled task along with another command which will create a different file that does not need this date in the command.

    example of commands I will be using:

    cautil "select conlog MSG='*forced*' START=18/DEC/2012 END=18/DEC/2012 LIST conlog expand=Y output=E:forced-CONLOG.log"
    rmtcntrl status > rmtcntrl-status.txt

    I could work this out in perl, however no perl here.

  • Frank

    I'm attempting to write a batch script to ping the entire scope of our network, then use the "good" replies back to get systeminfo for each IP address that comes back. I'm not sure if the below is correct but i know the systeminfo part is good. your assistance is much appreciated.

    : Turn off the echo
    @echo off
     
    : Setting the color of background and text
    color 0c
     
    : Display nothing but add whitespace
    echo.
     
    @echo OFF
    FOR /L %i IN (1,1,254) DO ping -n 1 x.x.x.%i
     
    : Displaying text
    echo Exporting System Info...
     
    systeminfo /s x.x.x.x | findstr /c:"Host Name" >\server
    systeminfo /s x.x.x.x | findstr /c:"System Model" >>\server
    systeminfo /s x.x.x.x | findstr /c:"[01]" >>\server
     
    echo.
    echo.
     
    echo Service Tag:
    wmic /node:x.x.x.x bios get serialnumber >>\server
  • Fred

    I am a computer noob that unwitting wandered onto this site.
    CAN SOMEONE TELL ME WHAT THE HELL IS GOING ON??!!

    • AskApache

      The sky is falling. GRTFM

  • CobaltDawg

    This is pretty awesome. Sadly, I'm still pretty new to scripting, but here's what I was thinking...

    I want to be able to run a script every x minutes that will check the status of a specific port. If the port shows activity, then check again in x minutes, but if the port is showing no activity, restart the PC..

    From what I've read, it should look something like this ... Is this correct? Any help would be greatly appreciated!

    REM CHECK PORT IS LISTENING (FOR SOCKISFIED TUNNEL)
    CALL :PORTCHECK %_PPORT%
    REM =======================================================================================
    REM =   PORTCHECK - Check that Port is being used (for tunnels)
    REM =======================================================================================
    :PORTCHECK
    netstat.exe -n -v -a -p TCP | FIND "ESTABLISHED" | FIND ":%~1" &>nul 2&>1
    IF ERRORLEVEL 1 CALL :SHUTDOWNIN
    SHUTDOWN -r -t "%~1" && EXIT /B
    EXIT /B
  • A Person

    Windows batch scripts look so ugly in comparison to Unix shell scripts: the inconsistent use of upper and lower case, generally much harder to read overall particularly for loops - e.g.

    for i in {1..5}
    do
        echo "Value: $i"
    done

    is clearly much easier to read.

    The constant use of && is also a nightmare, in comparison to the c-style semicolon terminator used in bash scripts.

    SET also seems pointless and completely illogical in comparison to other languages, where you can just do var=value;

    No idea what the guys at Microsoft were on when they invented batch scripting...

  • Thomas Elliott

    some pretty slick stuff here. thanks for sharing.

    • AskApache

      Just updated... make sure you download the actual src file.. and don't forget to install nircmd.

  • Thomas Elliott

    some pretty slick stuff here. thanks for sharing.

    • AskApache

      Just updated... make sure you download the actual src file.. and don't forget to install nircmd.

  • AskApache

    The sky is falling. GRTFM

  • mlesnews

    I love your examples, they are very helpful. I'm having a problem figuring out how to redirect a job to a log while running several jobs at the same time with start. I can redirect a job, 'myjob.exe >> mylog' and I can run several jobs at the same time via 'start myjob.exe' but if I try to do something like, 'start myjob.exe >> mylog' the output gets redirected to the screen and not the log file. I found a nice bit of C++ at http://stackoverflow.com/questions/1536205/running-another-program-in-windows-bat-file-and-not-create-child-process that allows me to background the jobs without a window but I cannot get either method, using 'start' or the 'c++' to update a log. So much easier in Unix... but it is what it is.

    Brief history of what I'm doing and why, I'm trying to cleanup saved games for Skyrim via http://skyrim.nexusmods.com/mods/31675 and the author runs his program in series which taking me a long time so I would prefer to run the job in parallel.

  • mlesnews

    I love your examples, they are very helpful. I'm having a problem figuring out how to redirect a job to a log while running several jobs at the same time with start. I can redirect a job, 'myjob.exe >> mylog' and I can run several jobs at the same time via 'start myjob.exe' but if I try to do something like, 'start myjob.exe >> mylog' the output gets redirected to the screen and not the log file. I found a nice bit of C++ at http://stackoverflow.com/questions/1536205/running-another-program-in-windows-bat-file-and-not-create-child-process that allows me to background the jobs without a window but I cannot get either method, using 'start' or the 'c++' to update a log. So much easier in Unix... but it is what it is.

    Brief history of what I'm doing and why, I'm trying to cleanup saved games for Skyrim via http://skyrim.nexusmods.com/mods/31675 and the author runs his program in series which taking me a long time so I would prefer to run the job in parallel.

  • Sanfords

    Specific problem I can't find the answer to online:
    I am cleaning up generated filenames and need to remove the * character from the names before renaming the files.
    But the %var:x=y% syntax won't work because * is treated specially.
    I have tried both:
    %var:*=x%
    and
    %var:"*"=x%
    and
    %var:^*=x%
    with no luck.
    What a maddening syntax!

  • THEsolver

    lol ive made such files too , do this :
    @echo off
    set a=0
    :one
    cls
    echo loading %a% %%
    ping localhost -n 2 >nul
    set a=%a%+1
    if %a%==100 goto two
    goto one
    :two
    echo 100 &&

    pause

    and... just pm me at brent1swaenen@hotmail.com ifu want one with a loading bar or somthing else...

  • AskApache

    That is really cool!

  • AskApache

    Nircmd


Related Articles


My Online Tools
Popular Articles


Hacking and Hackers

The use of "hacker" to mean "security breaker" is a confusion on the part of the mass media. We hackers refuse to recognize that meaning, and continue using the word to mean someone who loves to program, someone who enjoys playful cleverness, or the combination of the two. See my article, On Hacking.
-- Richard M. Stallman









[hide]

It's very simple - you read the protocol and write the code. -Bill Joy

Except where otherwise noted, content on this site is licensed under a Creative Commons Attribution 3.0 License, just credit with a link.
This site is not supported or endorsed by The Apache Software Foundation (ASF). All software and documentation produced by The ASF is licensed. "Apache" is a trademark of The ASF. NCSA HTTPd.
UNIX ® is a registered Trademark of The Open Group. POSIX ® is a registered Trademark of The IEEE.

+Askapache | askapache

Site Map | Contact Webmaster | License and Disclaimer | Terms of Service

↑ TOPMain